Static variable vs Class variable
Laszlo Nagy
gandalf at shopzeus.com
Tue Oct 9 18:46:36 CEST 2007
minkoo.seo at gmail.com wrote:
> Hi.
>
> I've got a question on the differences and how to define static and
> class variables. AFAIK, class methods are the ones which receives the
> class itself as an argument, while static methods are the one which
> runs statically with the defining class.
>
> Hence, my understanding is that static variables must be bound to the
> class defining the variables and shared by children of parent class
> where the variable is defined. But, please have a look at this code in
> which a guy told me that the variable a is static:
>
>
>>>> class Foo:
>>>>
> a = 1
> @classmethod
> def increment(cls):
> cls.a += 1
> print cls.a
>
In your increment() method, you do this:
cls.a += 1
It does the following thing:
#1. read cls.a
#2. add one
#3. assign this value to cls.a
In point #3, you really bind a name to a value. As you probably know, in
Python, there are names and objects. The initial value of the name 'a'
is 1. It is an immutable object. The "+=" operator usually increments a
value of an object. However, because the 'int' type is immutable, the +=
operator will rather rebind this variable to a newly created value. I
believe this is what is happening here. Your question "is variable a
static or class variable?" has no real answer. After running the
increment() method on a descendant class, e.g. Child1 will rebind the
name Child1.a, creating a new name in the namespace of the class. So the
variable Foo.a is still there, but you are accessing Child1.a instead.
If you want to HANDLE a as a static variable, you can handle it with a
static method. That won't bind a new name in the descendant class.
(However, you can still rebind it, e.g. "Child.a=42")
Now here is a good question: how do you handle a variable as static,
from a class (not static) method? Here is an example:
>>> class Foo(object):
... a = 1
... @classmethod
... def increment(cls):
... Foo.a += 1
... print cls.a
...
>>> class Child1(Foo):
... pass
...
>>> Child1.increment()
2
>>> Child1.increment()
3
>>> Foo.a
3
>>> Child1.a = 10
>>> Child1.increment()
10
>>> Child1.increment()
10
>>> Child1.increment()
10
>>> Foo.a
6
>>>
However, the question is: why would you do this? :-)
BTW you should use new style classes whenever it is possible. Old style
classes will have gone...
Hope this helps,
Laszlo
More information about the Python-list
mailing list