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

share|improve this question

feedback

10 Answers

up vote 239 down vote accepted

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

share|improve this answer
Anyone reading this should also read Daniel's answer way below; it's not strictly true that this is distinct from any instance-level "i" variable. This tripped me up until I read his clarifications below. – Dubslow Jul 27 at 3:00
1  
I'm just learning Python, but the advantages of @classmethod over @staticmethod AFAIK is that you always get the name of the class the method was invoked on, even if it's a subclass. A static method lacks this information, so it cannot call an overridden method, for example. – Seb Oct 2 at 15:58
feedback

@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
share|improve this answer
3  
that was a very nice description of pythons treatment for static variables. thanks – intiha Mar 3 '10 at 18:32
feedback

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
share|improve this answer
broken link on: static methods – zengr Apr 15 at 22:52
feedback

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.

share|improve this answer
feedback

One special thing to note about static properties & instance properties, shown in the example below:

class my_cls:
  my_prop = 0

#static property
print my_cls.my_prop  #--> 0

#assign value to static property
my_cls.my_prop = 1 
print my_cls.my_prop  #--> 1

#access static property thru' instance
my_inst = my_cls()
print my_inst.my_prop #--> 1

#instance property is different from static property 
#after being assigned a value
my_inst.my_prop = 2
print my_cls.my_prop  #--> 1
print my_inst.my_prop #--> 2

This means before assigning the value to instance property, if we try to access the property thru' instance, the static value is used. Each property declared in python class always has a static slot in memory.

share|improve this answer
feedback

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]
share|improve this answer
feedback

You could also enforce a class to be static using metaclass.

class StaticClassError(Exception):
    pass


class StaticClass:
    __metaclass__ = abc.ABCMeta

    def __new__(cls, *args, **kw):
        raise StaticClassError("%s is a static class and cannot be initiated."
                                % cls)

class MyClass(StaticClass):
    a = 1
    b = 3

    @staticmethod
    def add(x, y):
        return x+y

Then whenever by accident you try to initialize MyClass you'll get an StaticClassError.

share|improve this answer
feedback

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

share|improve this answer
feedback

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
share|improve this answer
feedback

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'
share|improve this answer
3  
This does not define class variables, just ordinary instance attributes. – Sebastian Rittau Sep 16 '08 at 11:30
feedback

Your Answer

 
or
required, but never shown
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.