Can I define a static method which I can call directly on the class instance? e.g.,
MyClass.the_static_method()
Yep, using the staticmethod decorator:
class MyClass(object):
#staticmethod
def the_static_method(x):
print(x)
MyClass.the_static_method(2) # outputs 2
Note that some code might use the old method of defining a static method, using staticmethod as a function rather than a decorator. This should only be used if you have to support ancient versions of Python (2.2 and 2.3):
class MyClass(object):
def the_static_method(x):
print(x)
the_static_method = staticmethod(the_static_method)
MyClass.the_static_method(2) # outputs 2
This is entirely identical to the first example (using #staticmethod), just not using the nice decorator syntax.
Finally, use staticmethod sparingly! There are very few situations where static-methods are necessary in Python, and I've seen them used many times where a separate "top-level" function would have been clearer.
The following is verbatim from the documentation::
A static method does not receive an implicit first argument. To declare a static method, use this idiom:
class C:
#staticmethod
def f(arg1, arg2, ...): ...
The #staticmethod form is a function decorator – see the description of function definitions in Function definitions for details.
It can be called either on the class (such as C.f()) or on an instance (such as C().f()). The instance is ignored except for its class.
Static methods in Python are similar to those found in Java or C++. For a more advanced concept, see classmethod().
For more information on static methods, consult the documentation on the standard type hierarchy in The standard type hierarchy.
New in version 2.2.
Changed in version 2.4: Function decorator syntax added.
I think that Steven is actually right. To answer the original question, then, in order to set up a class method, simply assume that the first argument is not going to be a calling instance, and then make sure that you only call the method from the class.
(Note that this answer refers to Python 3.x. In Python 2.x you'll get a TypeError for calling the method on the class itself.)
For example:
class Dog:
count = 0 # this is a class variable
dogs = [] # this is a class variable
def __init__(self, name):
self.name = name #self.name is an instance variable
Dog.count += 1
Dog.dogs.append(name)
def bark(self, n): # this is an instance method
print("{} says: {}".format(self.name, "woof! " * n))
def rollCall(n): #this is implicitly a class method (see comments below)
print("There are {} dogs.".format(Dog.count))
if n >= len(Dog.dogs) or n < 0:
print("They are:")
for dog in Dog.dogs:
print(" {}".format(dog))
else:
print("The dog indexed at {} is {}.".format(n, Dog.dogs[n]))
fido = Dog("Fido")
fido.bark(3)
Dog.rollCall(-1)
rex = Dog("Rex")
Dog.rollCall(0)
In this code, the "rollCall" method assumes that the first argument is not an instance (as it would be if it were called by an instance instead of a class). As long as "rollCall" is called from the class rather than an instance, the code will work fine. If we try to call "rollCall" from an instance, e.g.:
rex.rollCall(-1)
however, it would cause an exception to be raised because it would send two arguments: itself and -1, and "rollCall" is only defined to accept one argument.
Incidentally, rex.rollCall() would send the correct number of arguments, but would also cause an exception to be raised because now n would be representing a Dog instance (i.e., rex) when the function expects n to be numerical.
This is where the decoration comes in:
If we precede the "rollCall" method with
#staticmethod
then, by explicitly stating that the method is static, we can even call it from an instance. Now,
rex.rollCall(-1)
would work. The insertion of #staticmethod before a method definition, then, stops an instance from sending itself as an argument.
You can verify this by trying the following code with and without the #staticmethod line commented out.
class Dog:
count = 0 # this is a class variable
dogs = [] # this is a class variable
def __init__(self, name):
self.name = name #self.name is an instance variable
Dog.count += 1
Dog.dogs.append(name)
def bark(self, n): # this is an instance method
print("{} says: {}".format(self.name, "woof! " * n))
#staticmethod
def rollCall(n):
print("There are {} dogs.".format(Dog.count))
if n >= len(Dog.dogs) or n < 0:
print("They are:")
for dog in Dog.dogs:
print(" {}".format(dog))
else:
print("The dog indexed at {} is {}.".format(n, Dog.dogs[n]))
fido = Dog("Fido")
fido.bark(3)
Dog.rollCall(-1)
rex = Dog("Rex")
Dog.rollCall(0)
rex.rollCall(-1)
Yes, check out the staticmethod decorator:
>>> class C:
... #staticmethod
... def hello():
... print "Hello World"
...
>>> C.hello()
Hello World
You don't really need to use the #staticmethod decorator. Just declaring a method (that doesn't expect the self parameter) and call it from the class. The decorator is only there in case you want to be able to call it from an instance as well (which was not what you wanted to do)
Mostly, you just use functions though...
Static methods in Python?
Is it possible to have static methods in Python so I can call them
without initializing a class, like:
ClassName.StaticMethod()
Yes, static methods can be created like this (although it's a bit more Pythonic to use underscores instead of CamelCase for methods):
class ClassName(object):
#staticmethod
def static_method(kwarg1=None):
'''return a value that is a function of kwarg1'''
The above uses the decorator syntax. This syntax is equivalent to
class ClassName(object):
def static_method(kwarg1=None):
'''return a value that is a function of kwarg1'''
static_method = staticmethod(static_method)
This can be used just as you described:
ClassName.static_method()
A builtin example of a static method is str.maketrans() in Python 3, which was a function in the string module in Python 2.
Another option that can be used as you describe is the classmethod, the difference is that the classmethod gets the class as an implicit first argument, and if subclassed, then it gets the subclass as the implicit first argument.
class ClassName(object):
#classmethod
def class_method(cls, kwarg1=None):
'''return a value that is a function of the class and kwarg1'''
Note that cls is not a required name for the first argument, but most experienced Python coders will consider it badly done if you use anything else.
These are typically used as alternative constructors.
new_instance = ClassName.class_method()
A builtin example is dict.fromkeys():
new_dict = dict.fromkeys(['key1', 'key2'])
Perhaps the simplest option is just to put those functions outside of the class:
class Dog(object):
def __init__(self, name):
self.name = name
def bark(self):
if self.name == "Doggy":
return barking_sound()
else:
return "yip yip"
def barking_sound():
return "woof woof"
Using this method, functions which modify or use internal object state (have side effects) can be kept in the class, and the reusable utility functions can be moved outside.
Let's say this file is called dogs.py. To use these, you'd call dogs.barking_sound() instead of dogs.Dog.barking_sound.
If you really need a static method to be part of the class, you can use the staticmethod decorator.
Aside from the particularities of how static method objects behave, there is a certain kind of beauty you can strike with them when it comes to organizing your module-level code.
# garden.py
def trim(a):
pass
def strip(a):
pass
def bunch(a, b):
pass
def _foo(foo):
pass
class powertools(object):
"""
Provides much regarded gardening power tools.
"""
#staticmethod
def answer_to_the_ultimate_question_of_life_the_universe_and_everything():
return 42
#staticmethod
def random():
return 13
#staticmethod
def promise():
return True
def _bar(baz, quux):
pass
class _Dice(object):
pass
class _6d(_Dice):
pass
class _12d(_Dice):
pass
class _Smarter:
pass
class _MagicalPonies:
pass
class _Samurai:
pass
class Foo(_6d, _Samurai):
pass
class Bar(_12d, _Smarter, _MagicalPonies):
pass
...
# tests.py
import unittest
import garden
class GardenTests(unittest.TestCase):
pass
class PowertoolsTests(unittest.TestCase):
pass
class FooTests(unittest.TestCase):
pass
class BarTests(unittest.TestCase):
pass
...
# interactive.py
from garden import trim, bunch, Foo
f = trim(Foo())
bunch(f, Foo())
...
# my_garden.py
import garden
from garden import powertools
class _Cowboy(garden._Samurai):
def hit():
return powertools.promise() and powertools.random() or 0
class Foo(_Cowboy, garden.Foo):
pass
It now becomes a bit more intuitive and self-documenting in which context certain components are meant to be used and it pans out ideally for naming distinct test cases as well as having a straightforward approach to how test modules map to actual modules under tests for purists.
I frequently find it viable to apply this approach to organizing a project's utility code. Quite often, people immediately rush and create a utils package and end up with 9 modules of which one has 120 LOC and the rest are two dozen LOC at best. I prefer to start with this and convert it to a package and create modules only for the beasts that truly deserve them:
# utils.py
class socket(object):
#staticmethod
def check_if_port_available(port):
pass
#staticmethod
def get_free_port(port)
pass
class image(object):
#staticmethod
def to_rgb(image):
pass
#staticmethod
def to_cmyk(image):
pass
So, static methods are the methods which can be called without creating the object of a class.
For Example :-
#staticmethod
def add(a, b):
return a + b
b = A.add(12,12)
print b
In the above example method add is called by the class name A not the object name.
Summarizing others' answers and adding, there are many ways to declare Static Methods or Variables in python.
Using staticmethod() as a decorator:
One can simply put a decorator above a method(function) declared to make it a static method. For eg.
class Calculator:
#staticmethod
def multiply(n1, n2, *args):
Res = 1
for num in args: Res *= num
return n1 * n2 * Res
print(Calculator.multiply(1, 2, 3, 4)) # 24
Using staticmethod() as a parameter function:
This method can receive an argument which is of function type, and it returns a static version of the function passed. For eg.
class Calculator:
def add(n1, n2, *args):
return n1 + n2 + sum(args)
Calculator.add = staticmethod(Calculator.add)
print(Calculator.add(1, 2, 3, 4)) # 10
Using classmethod() as a decorator:
#classmethod has similar effect on a function as #staticmethod has, but
this time, an additional argument is needed to be accepted in the function (similar to self parameter for instance variables). For eg.
class Calculator:
num = 0
def __init__(self, digits) -> None:
Calculator.num = int(''.join(digits))
#classmethod
def get_digits(cls, num):
digits = list(str(num))
calc = cls(digits)
return calc.num
print(Calculator.get_digits(314159)) # 314159
Using classmethod() as a parameter function:
#classmethod can also be used as a parameter function, in case one doesn't want to modify class definition. For eg.
class Calculator:
def divide(cls, n1, n2, *args):
Res = 1
for num in args: Res *= num
return n1 / n2 / Res
Calculator.divide = classmethod(Calculator.divide)
print(Calculator.divide(15, 3, 5)) # 1.0
Direct declaration
A method/variable declared outside all other methods, but inside a class is automatically static.
class Calculator:
def subtract(n1, n2, *args):
return n1 - n2 - sum(args)
print(Calculator.subtract(10, 2, 3, 4)) # 1
The whole program
class Calculator:
num = 0
def __init__(self, digits) -> None:
Calculator.num = int(''.join(digits))
#staticmethod
def multiply(n1, n2, *args):
Res = 1
for num in args: Res *= num
return n1 * n2 * Res
def add(n1, n2, *args):
return n1 + n2 + sum(args)
#classmethod
def get_digits(cls, num):
digits = list(str(num))
calc = cls(digits)
return calc.num
def divide(cls, n1, n2, *args):
Res = 1
for num in args: Res *= num
return n1 / n2 / Res
def subtract(n1, n2, *args):
return n1 - n2 - sum(args)
Calculator.add = staticmethod(Calculator.add)
Calculator.divide = classmethod(Calculator.divide)
print(Calculator.multiply(1, 2, 3, 4)) # 24
print(Calculator.add(1, 2, 3, 4)) # 10
print(Calculator.get_digits(314159)) # 314159
print(Calculator.divide(15, 3, 5)) # 1.0
print(Calculator.subtract(10, 2, 3, 4)) # 1
Refer to Python Documentation for mastering OOP in python.
Python Static methods can be created in two ways.
Using staticmethod()
class Arithmetic:
def add(x, y):
return x + y
# create add static method
Arithmetic.add = staticmethod(Arithmetic.add)
print('Result:', Arithmetic.add(15, 10))
Output:
Result: 25
Using #staticmethod
class Arithmetic:
# create add static method
#staticmethod
def add(x, y):
return x + y
print('Result:', Arithmetic.add(15, 10))
Output:
Result: 25
You can use #staticmethod decorator to define a static method as shown below. In detail, I explain about #staticmethod decorator and #classmethod decorator in my answer for #classmethod vs #staticmethod in Python and also explain about instance method in my answer for What is an "instance method" in Python?:
class Person:
#staticmethod # Here
def test():
print("Test")
I encounter this question from time to time. The use case and example that I am fond of is:
jeffs#jeffs-desktop:/home/jeffs $ python36
Python 3.6.1 (default, Sep 7 2017, 16:36:03)
[GCC 6.3.0 20170406] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import cmath
>>> print(cmath.sqrt(-4))
2j
>>>
>>> dir(cmath)
['__doc__', '__file__', '__loader__', '__name__', '__package__', '__spec__', 'acos', 'acosh', 'asin', 'asinh', 'atan', 'atanh', 'cos', 'cosh', 'e', 'exp', 'inf', 'infj', 'isclose', 'isfinite', 'isinf', 'isnan', 'log', 'log10', 'nan', 'nanj', 'phase', 'pi', 'polar', 'rect', 'sin', 'sinh', 'sqrt', 'tan', 'tanh', 'tau']
>>>
It does not make sense to create an object of class cmath, because there is no state in a cmath object. However, cmath is a collection of methods that are all related in some way. In my example above, all of the functions in cmath act on complex numbers in some way.
I'm having some problems. How we can define a function outside of a function that can be used in a class property? Also, how we can insert the self parameter into the function signature? I would like to visualize it like this:
>>> def a(self, x): #I thought maybe class will give "self" to this property function
... print(self)
...
>>> class aa:
... def __init__(self):
... pass
... #a
... def p():
... print('in it')
...
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "<stdin>", line 4, in aa
TypeError: a() missing 1 required positional argument: 'x'
I want to define a function outside but to use inside of a class. Like a class's method as a property. How can I do this?
It's not really clear what you want your out-of-class function to do. There are a bunch of possibilities, but you may not know the terminology yet to describe it to us.
Here's the three I think are most likely:
You may want your function to be a decorator. That means you can apply it to a method with #decorator syntax to other functions, including methods in a class.
For this to work, your function needs to be written to accept a function object as its only argument. Whatever it returns is what will replace the function or method it was being called on, so usually you want to return a callable, but you could instead return a descriptor like property does. Try something like this:
def decorator(func):
def wrapper(self, *args, **kwargs):
print("in the wrapper")
result = func(self, *args, **kwargs)
print("wrapper is done")
return result
return wrapper
class Foo:
#decorator
def foo(self, x):
print("in foo(), x is", x)
f = Foo()
f.foo(1) # prints three messages
When you call the foo method, you're actually going to be calling the wrapper method that the decorator returned after it was applied to the original method (func). Because of how we wrote the wrapper, it will call func so the original method prints out its message too.
You may want to use property (a descriptor type) to call your out-of-class function. This is a less common way of using property than applying it as a decorator on a method, but it's not impossible. You could even have two different functions, one to be called when requesting the attribute, the other than will be called when setting it (but I'll demonstrate with just the getter):
def getter(obj):
print("in the getter")
return 1
class Foo2:
foo = property(getter)
f2 = Foo2()
print(f2.foo) # prints a message from the getter function first, then prints 1
Note that you can't use #decorator syntax when building a property this way. That is only legal syntax immediately before a function definition, and we're not defining any functions that way inside our class.
You may just want to copy a function defined outside of the class into it, without any decorator or property nonsense. This is the easiest one to do, it's just a simple assignment:
def func(self, x):
print("x is", x)
class Foo3:
method = func # just assign the global to a name in the class body
func = func # you can even use the same name if you don't mind confusing people
f3 = Foo3()
f3.method(1)
f3.func(2)
If you want to create a property that uses a function defined outside your class, it would be something like this:
def myfunc(self):
return self._p
class Foo:
def __init__(self, p):
self._p = p
p = property(myfunc)
f = Foo("Alpha")
f.p # gives "Alpha"
property accepts a function as its (first) argument. The function should have self as a parameter, and should return the value that you want the property to evaluate to.
Say I have an class that looks like this:
class Test(object):
def __init__(self, a, b):
self.a = a
self.b = b
self.c = self.a + self.b
I would like the value of self.c to change whenever the value of attributes self.a or self.b changes for the same instance.
e.g.
test1 = Test(2,4)
print test1.c # prints 6
test1.a = 3
print test1.c # prints = 6
I know why it would still print 6, but is there a mechanism I could use to fire an update to self.c when self.a has changed. Or the only option I have is to have a method that returns me the value of self.c based on the current state of self.a and self.b
Yes, there is! It's called properties.
Read Only Properties
class Test(object):
def __init__(self,a,b):
self.a = a
self.b = b
#property
def c(self):
return self.a + self.b
With the above code, c is now a read-only property of the Test class.
Mutable Properties
You can also give a property a setter, which would make it read/write and allow you to set its value directly. It would look like this:
class Test(object):
def __init__(self, c = SomeDefaultValue):
self._c = SomeDefaultValue
#property
def c(self):
return self._c
#c.setter
def c(self,value):
self._c = value
However, in this case, it would not make sense to have a setter for self.c, since its value depends on self.a and self.b.
What does #property mean?
The #property bit is an example of something called a decorator. A decorator actually wraps the function (or class) it decorates into another function (the decorator function). After a function has been decorated, when it is called it is actually the decorator that is called with the function (and its arguments) as an argument. Usually (but not always!) the decorated function does something interesting, and then calls the original (decorated) function like it would normally. For example:
def my_decorator(thedecoratedfunction):
def wrapped(*allofthearguments):
print("This function has been decorated!") #something interesting
thedecoratedfunction(*allofthearguments) #calls the function as normal
return wrapped
#my_decorator
def myfunction(arg1, arg2):
pass
This is equivalent to:
def myfunction(arg1, arg2):
pass
myfunction = my_decorator(myfunction)
So this means in the class example above, instead of using the decorator you could also do this:
def c(self):
return self.a + self.b
c = property(c)
They are exactly the same thing. The #property is just syntactic sugar to replace calls for myobject.c with the property getter and setter (deleters are also an option).
Wait - How does that work?
You might be wondering why simply doing this once:
myfunction = my_decorator(myfunction)
...results in such a drastic change! So that, from now on, when calling:
myfunction(arg1, arg2)
...you are actually calling my_decorator(myfunction), with arg1, arg2 sent to the interior wrapped function inside of my_decorator. And not only that, but all of this happens even though you didn't even mention my_decorator or wrapped in your function call at all!
All of this works by virtue of something called a closure. When the function is passed into the decorator in this way (e.g., property(c)), the function's name is re-bound to the wrapped version of the function instead of the original function, and the original function's arguments are always passed to wrapped instead of the original function. This is simply the way that closures work, and there's nothing magical about it. Here is some more information about closures.
Descriptors
So to summarize so far: #property is just a way of wrapping the class method inside of the property() function so the wrapped class method is called instead of the original, unwrapped class method. But what is the property function? What does it do?
The property function adds something called a descriptor to the class. Put simply, a descriptor is an object class that can have separate get, set, and delete methods. When you do this:
#property
def c(self):
return self._c
...you are adding a descriptor to the Test class called c, and defining the get method (actually, __get__()) of the c descriptor as equal to the c(self) method.
When you do this:
#c.setter
def c(self,value):
self._c
...you are defining the set method (actually, __set__()) of the c descriptor as equal to the c(self,value) method.
Summary
An amazing amount of stuff is accomplished by simply adding #property to your def c(self) method! In practice, you probably don't need to understand all of this right away to begin using it. However, I recommend keeping in mind that when you use #property, you are using decorators, closures, and descriptors, and if you are at all serious about learning Python it would be well worth your time to investigate each of these topics on their own.
The simplest solution is to make c a read-only property:
class Test(object):
def __init__(self, a, b):
self.a = a
self.b = b
#property
def c(self):
return self.a + self.b
Now every time you access test_instance.c, it calls the property getter and calculates the appropriate value from the other attributes. In use:
>>> t = Test(2, 4)
>>> t.c
6
>>> t.a = 3
>>> t.c
7
Note that this means that you cannot set c directly:
>>> t.c = 6
Traceback (most recent call last):
File "<pyshell#16>", line 1, in <module>
t.c = 6
AttributeError: can't set attribute