namespace question

X

xixiliguo

c = [1, 2, 3, 4, 5]
class TEST():
c = [5, 2, 3, 4, 5]
def add( self ):
c[0] = 15

a = TEST()


a.add()

print( c, a.c, TEST.c )

result :
[15, 2, 3, 4, 5] [5, 2, 3, 4, 5] [5, 2, 3, 4, 5]


why a.add() do not update c in Class TEST? but update c in main file
 
C

Chris Rebert

c = [1, 2, 3, 4, 5]
class TEST():
   c = [5, 2, 3, 4, 5]

That line creates a class (i.e. "static") variable, which is unlikely
to be what you want. Instance variables are normally created in the
body of an __init__() method.
   def add( self ):
       c[0] = 15

a = TEST()


a.add()

print( c, a.c, TEST.c )

result :
[15, 2, 3, 4, 5] [5, 2, 3, 4, 5] [5, 2, 3, 4, 5]


why a.add() do not update c in Class TEST? but update c in main file

Python is not Java (or similar). To refer to instance variables, you
must explicitly use `self`; i.e. use "self.c[0] = 15" in add().

I would recommend reviewing the relevant section of the Python tutorial:
http://docs.python.org/tutorial/classes.html

Cheers,
Chris
 
J

Jean-Michel Pichavant

xixiliguo said:
c = [1, 2, 3, 4, 5]
class TEST():
c = [5, 2, 3, 4, 5]
def add( self ):
c[0] = 15

a = TEST()


a.add()

print( c, a.c, TEST.c )

result :
[15, 2, 3, 4, 5] [5, 2, 3, 4, 5] [5, 2, 3, 4, 5]


why a.add() do not update c in Class TEST? but update c in main file

Attributes can only accessed by explictly naming the owner, unlike some
other languages which infer 'this/self'.
When an attribute is not found in the owner, python may look into the
"outer" namespace. Read the python documentation for an accurate
description.


Here is an illustration (python 2.5):

c='global'

class TEST():
c = 'class'
d = 'classonly'
def __init__(self):
self.c='instance'
def test(self):
print c
print TEST.c
print self.c
print self.d # this is valid, if d is not found in the instance,
python will look into the class

t = TEST()

t.test()

global
class
instance
classonly


Note that objects in python are properly named namespaces. locals and
globals are not, so be careful while naming those (in few words: don't
use globals)

c = 'global'

def foo():
c = 'local'
print c # same name for 2 different objects

def bar():
print c
global c # the global statement is quite strange, it applies to the
whole block, even previous statements, ppl usually put it at the
begining of the block though

foo()
bar()

'local'
'global'

Cheers,

JM
 
D

David

Your code updated to show the difference between a variable, a class
variable, and an instance variable.
c = [1, 2, 3, 4, 5]
class TEST():
c = [5, 2, 3, 4, 5] ## class variable (TEST.c)
def __init__(self):
self.c = [1, 2, 3, 4, 5] ## instance variable (a.c)

def add(self, c):
self.c[0] = 15 ## instance variable
TEST.c[0] = -1 ## class variable
c[0] = 100 ## variable/list
return c

a = TEST()
c = a.add(c)
print( c, a.c, TEST.c )
 
S

Steven D'Aprano

Your code updated to show the difference between a variable, a class
variable, and an instance variable.

The preferred terms in Python circles are class and instance
*attributes*, not variables.

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.

Therefore a class variable is a variable holding a class, and an instance
variable is a variable holding an instance.

Yes, in Python, classes and types are first-class objects (pun not
intended), and it is quite common to store them in variables:

for cls in (int, float, Decimal, Fraction, myint, myfloat):
do_something_with(cls)


Other languages may choose to use illogical terminology if they choose.
 
M

Mark Lawrence

The preferred terms in Python circles are class and instance
*attributes*, not variables.

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.

Therefore a class variable is a variable holding a class, and an instance
variable is a variable holding an instance.

Yes, in Python, classes and types are first-class objects (pun not
intended), and it is quite common to store them in variables:

for cls in (int, float, Decimal, Fraction, myint, myfloat):
do_something_with(cls)


Other languages may choose to use illogical terminology if they choose.

Surely you mean names, not variables? :)
 
S

Steven D'Aprano

Surely you mean names, not variables? :)

Well yes, I do, but the idea of classes being first class objects is
radical enough to some people without also introducing them to the idea
that there are no variables at all!

I'm very aware that name binding is not quite the same as variables in
some other languages, but the difference is subtle and doesn't mean that
the term "variable" is owned by Pascal- or C-like languages. It just
means that, like most computer science terms, "variable" has subtle
differences from implementation to implementation.
 
S

Steven D'Aprano

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.
 
S

Steven D'Aprano

Names don't hold anything. Not in natural language, and not in Python.

I don't agree, I think the analogy of "holding on to", or "holding",
works well for names in this context. A *binding* (the term you prefer)
refers to the process of *tying* two objects together with rope, string,
or twine such that they *hold fast*. If names don't hold values, neither
can they be bound.

I would be surprised if many programmers, whether experienced or not, or
even non-programmers, failed to grasp the concept of a name "holding" a
value. (And I point out that to *grasp a concept* is also to hold on to
it. We hold our loved ones dear even when they are on the other side of
the world, we hold these truths to be self-evident, and we don't hold
with that sort of behaviour -- surely we are capable of holding onto the
idea that names can hold values?)

But rather than spend any more time trying to convince you to hold a
different opinion, I will accept your criticism and rephrase my earlier
statement:

A string variable is a symbolic identifier given to a value and capable
of being varied, which is given to a value which is a string.

Python has these -- it has names, which are symbolic identifiers given to
values, and those name:value bindings are capable of varying. It has
strings. And you can bind names to strings. Ergo, it has string variables.

I acknowledge that when I say "string variable", I mean a variable whose
value is a string *at this moment*, I don't mean a variable which is
prohibited by the compiler from taking a non-string value.

To the extent that careless use of the term variable may confuse the
naive reader who assumes that Python is just like Pascal (or any other
statically typed language), it is sometimes useful to emphasis the
differences by talking about "name bindings". But sometimes it is useful
to emphasis the similarities, in which case "name binding" is obfuscatory
and "variable" is perfectly reasonable.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,744
Messages
2,569,482
Members
44,900
Latest member
Nell636132

Latest Threads

Top