namespace question

Steven D'Aprano steve+comp.lang.python at pearwood.info
Sun Feb 26 08:40:03 EST 2012


On Sun, 26 Feb 2012 19:47:49 +1100, Ben Finney wrote:

>> An integer variable is a variable holding an integer. A string variable
>> is a variable holding a string. A list variable is a variable holding a
>> list.
> 
> And Python has none of those. Its references don't “hold” anything.

Ah, but they do. Following the name binding:

x = 1

the name "x" now holds a reference to an int, or if you want to cut out 
one layer of indirection, the name "x" holds an int. That is to say, the 
value associated with the name "x" is an int.

I don't believe this is a troublesome concept.


> I appreciate that you think “variable” is a useful term in Python, but
> this kind of mangling of the concept convinces me that it's not worth
> it.

I'm not sure that there is any mangling here. Or at least, the concept is 
only mangled if you believe that Pascal- or C-like variables (named 
memory locations) are the one true definition of "variable". I do not 
believe this.

Words vary in their meanings, pun not intended, and in the same way that 
the semantics of classes in (say) Java are not identical to the semantics 
of classes in Python, so I think that it is perfectly reasonable to talk 
about Python having variables, implemented using bindings to objects in a 
namespace, even though the semantics of Python variables is slightly 
different from that of C variables.

Fundamentally, a variable is a name associated with a value which can 
vary. And Python name bindings meet that definition no less than C fixed 
memory locations.


> Python doesn't have variables, and even if you want to say “variables”
> when you mean “references”, there's no such thing as a “string variable”
> etc. in Python. References don't have types, so its needlessly confusing
> to perpetuate that kind of thinking.

But objects have types, and it makes sense to state that the type of the 
name is the type of the object bound to that name, at least for the 
duration of the binding. That's exactly what we write in Python:

type(x)

tells us the type of x, whatever x happens to be. There's no implication 
that it is the type of the *name* x, since names are not typed.

More importantly, while Python doesn't have static types, in real code, 
names generally are expected to be bound to objects of a particular type 
(perhaps a duck-type, but still a type). It is rare to have code 
including a name bound to *anything at all* -- the main counter-example I 
can think of is the id() function. Generally, names are expected to be 
bound to a specific kind of value: perhaps as specific as "a string", or 
as general as "an iterable", or "anything with a __add__ method", but 
nevertheless there is the expectation that if the name is bound to 
something else, you will get an error. A compile time error in C, a 
runtime error in Python, but either way, the expectation is that you get 
an error.

In an example like this:

def spam(some_string):
    return some_string.upper() + "###"

I maintain that it is reasonable to say that "some_string is a string 
variable", since that expresses the programmer's intention that 
some_string should be bound to string objects (modulo duck-typing). If 
Python were statically typed, then passing some_string=42 would cause a 
compile-time error. In Python, you get a runtime error instead. I don't 
believe this invalidates the idea that some_string is intended to be a 
string.

Or to make this painfully complete: some_string is a name linked to a 
value which can vary (hence a variable) intended to be limited to strings 
(hence a string variable). Python may not enforce this to the same extent 
as C or Haskell or Pascal, but the concept still holds.


-- 
Steven



More information about the Python-list mailing list