[Tutor] class functions/staticmethod?
Peter Otten
__peter__ at web.de
Mon Aug 12 04:10:24 EDT 2019
James Hartley wrote:
> I am lacking in understanding of the @staticmethod property.
> Explanation(s)/links might be helpful. I have not found the descriptions
> found in the Internet wild to be particularly instructive. Given the code
> below:
> =====8<------------------
> from collections import namedtuple
>
> class Foo():
> Dimensions = namedtuple('Dimensions', ['height', 'width'])
> _dimensions = Dimensions(3, 4)
>
> def dimensions():
> print('id = {}'.format(id(Foo._dimensions)))
> return Foo._dimensions
That works with the class as Foo.dimensions is just a function in Python 3,
but not with an instance because Python will try to pass the instance as the
first argument
>>> Foo.dimensions()
id = 140192821560880
Dimensions(height=3, width=4)
>>> Foo().dimensions()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: dimensions() takes 0 positional arguments but 1 was given
You can turn it into a static method
@staticmethod
def dimensions():
print('id = {}'.format(id(Foo._dimensions)))
return Foo._dimensions
>>> Foo.dimensions()
id = 139629779179056
Dimensions(height=3, width=4)
>>> Foo().dimensions()
id = 139629779179056
Dimensions(height=3, width=4)
or, when you are planning for subclases, into a classmethod:
$ cat staticmethod_demo.py
class Foo():
_dimensions = "foo-dimensions"
@classmethod
def class_dimensions(cls):
return cls._dimensions
@staticmethod
def static_dimensions():
return Foo._dimensions
class Bar(Foo):
_dimensions = "bar-dimensions"
$ python3 -i staticmethod_demo.py
>>> Foo.class_dimensions(), Foo.static_dimensions()
('foo-dimensions', 'foo-dimensions')
>>> Bar.class_dimensions(), Bar.static_dimensions()
('bar-dimensions', 'foo-dimensions')
>
> @staticmethod
> def dimensions1():
> print('id = {}'.format(id(_dimensions)))
> return _dimensions
> =====8<------------------
> The class method Foo.dimensions() is capable of accessing class members,
> but Foo.dimensions1() cannot. What does the @staticmethod decorator really
> add?
You do not really need static methods; they work like module-level
functions. They are more of a means to organize your code; by writing
class Foo:
@staticmethod
def bar(...):
do stuff
instead of
def foo_bar(...):
do stuff
class Foo:
pass
you make the mental association between the class and the function a bit
stronger.
More information about the Tutor
mailing list