views:

107

answers:

3

Could you clarify some ideas behind Python classes and class instances?

Consider this:

class A():
    name = 'A'

a = A()

a.name = 'B' # point 1 (instance of class A is used here)

print a.name
print A.name

prints:

B
A

if instead in point 1 I use class name, output is different:

A.name = 'B' # point 1 (updated, class A itself is used here)

prints:

B
B

Even if classes in Python were some kind of prototype for class instances, I'd expect already created instances to remain intact, i.e. output like this:

A
B

Can you explain what is actually going on?

+4  A: 

First of all, the right way in Python to create fields of an instance (rather than class fields) is using the __init__ method. I trust that you know that already.

Python does not limit you in assigning values to non-declared fields of an object. For example, consider the following code:

class Empty: pass
e = Empty()
e.f = 5
print e.f # shows 5

So what's going in your code is:

  1. You create the class A with a static field name assigned with A.
  2. You create an instance of A, a.
  3. You create a new field for the object a (but not for other instances of A) and assign B to it
  4. You print the value of a.name, which is unique to the object a.
  5. You print the value of the static field A.name, which belongs to the class
Little Bobby Tables
+1  A: 

You also should look at these SO threads for further explanations:
http://stackoverflow.com/questions/68645/python-static-variable
http://stackoverflow.com/questions/707380/in-python-how-can-i-access-static-class-variables-within-class-methods

And an official tutorial: http://docs.python.org/tutorial/classes.html#SECTION0011320000000000000000

Keep in mind that the assignment "=" operator in python behaves differently than C++ or Java:
http://docs.python.org/reference/simple_stmts.html#assignment-statements

Thorfin
A: 

Perhaps this example may make things more help clarify. Recall that Python names are not storage (as variables are in other languages) but references to storage. You can find what a name refers to with id(name). The identity operator x is y tells whether two names point at the same object.

>>> class A(object):
...     name = 'A'
... 
>>> x = A()
>>> A.name is x.name
True
>>> x.name = 'fred'  # x.name was bound to a new object (A.name wasn't)
>>> A.name is x.name
False
>>> x = A()          # start over
>>> A.name is x.name
True                 # so far so good
>>> A.name = 'fred'
>>> A.name is x.name 
True                 # this is somewhat counter-intuitive
msw