views:

20540

answers:

8

Is it possible to have static class variables or methods in python? What syntax is required to do this?

+13  A: 

Yes. You can have static methods using the @staticmethod decorator.

Also, if I am interpreting your question correctly, you can define static fields by declaring them just after your class name, like so (with example):

class test:
    var=5   #static field

t = test()  #example object 1
print t.var #should be 5
t2 = test() #example object 2
t.var = 2
print t.var #should be 2 now
Steve Johnson
+52  A: 

Variables declared inside the class definition, but not inside a method are class or static variables:

>>> class MyClass:
...     i = 3
...
>>> MyClass.i
3

As @Daniel points out, this creates a class-level "i" variable, but this is distinct from any instance-level "i" variable, so you could have

>>> m = MyClass()
>>> m.i = 4
>>> MyClass.i, m.i
>>> (3, 4)

This is different from C++ and Java, but no so different from C#, where a static variable can't be accessed from an instance at all.

See what the Python tutorial has to say on the subject of classes and class objects.

@Steve Johnson has already answered regarding static methods, also documented under "Built-in Functions" in the Python Library Reference.

class C:
    @staticmethod
    def f(arg1, arg2, ...): ...

@beidy recommends classmethods over staticmethod, as the method then receives the class type as the first argument, but I'm still a little fuzzy on the advantages of this approach over staticmethod. If you are too, then it probably doesn't matter.

Blair Conrad
A: 

A way to define instance variables (which in this case act effectively as class variables) is:

class Cell_Grid(UserDict):
    def __init__(self):
        self.foo = 'bar'
        self.baz = 'qux'
akdom
This does not define class variables, just ordinary instance attributes.
Sebastian Rittau
+2  A: 

Personally I would use a classmethod whenever I needed a static method. Mainly because I get the class as an argument.

class myObj(object):
   def myMethod(cls)
     ...
   myMethod = classmethod(myMethod)

or use a decorator

class myObj(object):
   @classmethod
   def myMethod(cls)

For static properties.. Its time you look up some python definition.. variable can always change. There are two types of them mutable and immutable.. Also, there are class attributes and instance attributes.. Nothing really like static attributes in the sense of java & c++

Why use static method in pythonic sense, if it has no relation whatever to the class! If I were you, I'd either use classmethod or define the method independent from the class.

beidy
A: 

Static methods in python are called classmethods. Take a look at the following code

>>> class MyClass:
...    def myInstanceMethod(self):
...        print 'output from an instance method'
...    @classmethod
...    def myStaticMethod(cls):
...        print 'output from a static method'
>>> MyClass.myInstanceMethod()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: unbound method myInstanceMethod() must be called [...]
>>> MyClass.myStaticMethod()
output from a static method

Notice that when we call the method myInstanceMethod we get an error, this is because it requires that method be called on an instance of this class. The method myStaticMethod is set as a classmethod using the decorator @classmethod.

Just for kicks and giggles, we could call myInstanceMethod on the class by passing in an instance of the class, like so

>>> MyClass.myInstanceMethod(MyClass())
output from an instance method
wbowers
+26  A: 

@Blair Conrad said static variables declared inside the class definition, but not inside a method are class or "static" variables:

>>> class Test(object):
...     i = 3
...
>>> Test.i
3

There are a few gotcha's here. Carrying on from the example above:

>>> t = Test()
>>> t.i     # static variable accessed via instance
3
>>> t.i = 5 # but if we assign to the instance ...
>>> Test.i  # we have not changed the static variable
3
>>> t.i     # we have overwritten Test.i on t by creating a new attribute t.i
5
>>> Test.i = 6 # to change the static variable we do it by assigning to the class
>>> t.i
5
>>> Test.i
6

Notice how the instance variable 't.i' got out of sync with the "static" class variable when the attribute 'i' was set directly on 't'. This is because 'i' was re-bound within the 't' namespace, which is distinct from the 'Test' namespace. If you want to change the value of a "static" variable, you must change it within the scope (or object) where it was originally defined. I put "static" in quotes because Python does not really have static variables in the sense that C++ and Java do.

Although it doesn't say anything specific about static variables or methods, the Python tutorial has some relevant information on classes and class objects.

@Steve Johnson also answered regarding static methods, also documented under "Built-in Functions" in the Python Library Reference.

class Test(object):
    @staticmethod
    def f(arg1, arg2, ...):
        ...

@beid also mentioned classmethod, which is similar to staticmethod. A classmethod's first argument is the class object. Example:

class Test(object):
    i = 3 # class (or static) variable
    @classmethod
    def g(cls, arg):
        # here we can use 'cls' instead of the class name (Test)
        if arg > cls.i:
            cls.i = arg # would the the same as  Test.i = arg1
Daniel
that was a very nice description of pythons treatment for static variables. thanks
intiha
A: 

To avoid any potential confusion, I would like to contrast static variables and immutable objects.

Some primitive object types like integers, floats, strings, and touples are immutable in Python. This means that the object that is referred to by a given name cannot change if it is of one of the aforementioned object types. The name can be reassigned to a different object, but the object itself may not be changed.

Making a variable static takes this a step further by disallowing the variable name to point to any object but that to which it currently points. (Note: this is a general software concept and not specific to Python; please see others' posts for information about implementing statics in Python).

Ross
A: 

You can also add class variables to classes on the fly

>>> class X:
...     pass
... 
>>> X.bar = 0
>>> x = X()
>>> x.bar
0
>>> x.foo
Traceback (most recent call last):
  File "<interactive input>", line 1, in <module>
AttributeError: X instance has no attribute 'foo'
>>> X.foo = 1
>>> x.foo
1

And class instances can change class variables

class X:
  l = []
  def __init__(self):
    self.__class__.l.append(1)

print X().l
print X().l

>python test.py
[1]
[1, 1]
Gregory