It used to matter more back in Python 2, where the instance-ness of instance methods was enforced more strongly:
>>> class B:
... def f(x):
... print("x is", x)
...
>>> B.f(1)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: unbound method f() must be called with B instance as first argument (
got int instance instead)
You had to mark static methods with @staticmethod back then.
These days, @staticmethod still makes it clearer that the method is static, which helps with code readability and documentation generation, and it lets you call the method on instances without the system trying to bind self.
It used to matter more back in Python 2, where the instance-ness of instance methods was enforced more strongly:
>>> class B:
... def f(x):
... print("x is", x)
...
>>> B.f(1)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: unbound method f() must be called with B instance as first argument (
got int instance instead)
You had to mark static methods with @staticmethod back then.
These days, @staticmethod still makes it clearer that the method is static, which helps with code readability and documentation generation, and it lets you call the method on instances without the system trying to bind self.
Try these two classes, both having a cry method, one as a classmethod and another as a staticmethod with self passed on
class Cat:
def __init__(self):
self.sound = "meow"
def cry(self):
print(self.sound)
x = Cat()
x.cry()
meow
and with another class
class Dog:
def __init__(self):
self.sound = "ruff-ruff"
@staticmethod
def cry(self):
print(self.sound)
x = Dog()
x.cry()
TypeError: cry() missing 1 required positional argument: 'self'
and we can see the @staticmethod decorator basically removed the passed in self
Python decorator as a staticmethod - Stack Overflow
Confused about decorators, classmethod and staticmethod
@staticmethod vs @classmethod vs functions outside of class in Python - Software Engineering Stack Exchange
@staticmethod called outside class scope (?)
Videos
This is not how staticmethod is supposed to be used. staticmethod objects are descriptors that return the wrapped object, so they only work when accessed as classname.staticmethodname. Example
class A(object):
@staticmethod
def f():
pass
print A.f
print A.__dict__["f"]
prints
<function f at 0x8af45dc>
<staticmethod object at 0x8aa6a94>
Inside the scope of A, you would always get the latter object, which is not callable.
I'd strongly recommend to move the decorator to the module scope -- it does not seem to belong inside the class. If you want to keep it inside the class, don't make it a staticmethod, but rather simply del it at the end of the class body -- it's not meant to be used from outside the class in this case.
Python classes are created at runtime, after evaluating the contents of the class declaration. The class is evaluated by assigned all declared variables and functions to a special dictionary and using that dictionary to call type.__new__ (see customizing class creation).
So,
class A(B):
c = 1
is equivalent to:
A = type.__new__("A", (B,), {"c": 1})
When you annotate a method with @staticmethod, there is some special magic that happens AFTER the class is created with type.__new__. Inside class declaration scope, the @staticmethod function is just an instance of a staticmethod object, which you can't call. The decorator probably should just be declared above the class definition in the same module OR in a separate "decorate" module (depends on how many decorators you have). In general decorators should be declared outside of a class. One notable exception is the property class (see properties). In your case having the decorator inside a class declaration might make sense if you had something like a color class:
class Color(object):
def ___init__(self, color):
self.color = color
def ensure_same_color(f):
...
black = Color("black")
class TFord(object):
def __init__(self, color):
self.color = color
@black.ensure_same_color
def get():
return 'Here is your shiny new T-Ford'
Hi r/learnpython, I'm currently working through djangoforbeginners and encountered the usage of classmethod() as a decorator for testing using setUpTestData().
I'm really trying to get comfortable reading the docs, but I feel like the explanations are using other terms I don't really understand to explain it, and feel like it's just looping into each other without a dumbed down explanation.
From what I could gather reading the docs, decorators make the code look neater in a similar(?) sense that list comprehension make it easier to read? I also don't quite understand what classmethod and staticmethod does that's different to just defining your own function. What do they mean by staticmethod not receiving an "implicit argument" vs. classmethod which does?
Please help an absolute clean slate beginner here! TIA.
If your method calls a static method on the class, then it does require information on the class. You have a class method, not a static method. By declaring it @classmethod (and adding the cls parameter), you not only properly inform the reader, you allow polymorphism. An inheritor can reimplement the called static method and change behavior.
Python's static methods are intended for methods that are part of a class, and can be called as either a class method or an instance method: both Class.the_method() and self.the_method() would work. When the static method is called, it is not given an implicit first argument:
class Example:
def instance_method_example(self, arguments):
...
@classmethod
def class_method_example(cls, arguments):
...
@staticmethod
def static_method_example(arguments):
...
If you merely want to create a helper function that is used within your class, do not use @staticmethod. Define a free function outside of the class. For example:
class Example:
def some_method(self, argument):
return _helper(argument, self.x)
def _helper(a, b):
...
The background of static methods in Python is the following: when you access an attribute of an object x.attribute or getattr(x, 'attribute'), then this name is looked up in the instance dict or the class dict. If an object is found in the class dict, it is checked whether that object is a “descriptor”: an object that describes how this attribute behaves, not an object that would be directly returned. Descriptors have dunder-methods like __get__, __set__, and __del__ that are invoked depending on whether the descriptor is accessed, assigned to, or deleted with the del operator.
Functions – the things you declare with def – are descriptors. By default, the __get__ descriptor binds the function to the instance argument (typically called self) and returns the bound function, so that it can be invoked as a method. But the various decorators change this behaviour:
- a
@classmethod defbinds to the class object, not the instance - a
@staticmethod defdoes not bind to any object and just returns the underlying function directly - a
@propertyinvokes the underlying function to retrieve a value
These differences are (partially) visible when looking at the repr() of the bound methods. With the first Example class:
instance_method_example- with class:
Example.instance_method_example
is<function Example.instance_method_example at 0x7f1dfdd6fd30>,
the unbound function - with instance:
<function Example.instance_method_example at 0x7f1dfdd6fd30>
is<bound method Example.instance_method_example of <__main__.Example object at 0x7f1dfdddcb80>>,
a method bound to the instance
- with class:
class_method_example- with class:
Example.class_method_example
is<bound method Example.class_method_example of <class '__main__.Example'>>,
a method bound to the class - with instance:
Example().class_method_example
is<bound method Example.class_method_example of <class '__main__.Example'>>,
also a method bound to the class
- with class:
static_method_example- with class:
Example.static_method_example
is<function Example.static_method_example at 0x7f1dfdd6fe50>,
the unbound function - with instance:
Example().static_method_example
is<function Example.static_method_example at 0x7f1dfdd6fe50>,
also the unbound function
- with class:
As a table:
| invoked on… | no decorator | @classmethod |
@staticmethod |
|---|---|---|---|
| … instance | bound to instance | bound to class | unbound |
| … class | unbound | bound to class | unbound |
Hello. I'm having a hard time wrapping my brain around what the staticmethod decorator does for me. From what I've read, it allows me to access the class method without instantiation.... got it. But it seems that I can do that anyway.
class Fruit:
def some_func(some_text):
print(some_text)
class Fruitas:
@staticmethod
def algo_func(algo_texto):
print(algo_texto)
Fruit.some_func('hello, world')
Fruitas.algo_func('hola, mundo')hello, world
hola, mundo
Why do people say that it offers access to the method without instantiation? Any insight is greatly appreciated.
Looked so far: python.org, pythonbasics.org, /learnpython 'staticmethod', various online tutorials, o'reilly python book.