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.

_______________________________________________
Tutor maillist  -  Tutor@python.org
To unsubscribe or change subscription options:
https://mail.python.org/mailman/listinfo/tutor

Reply via email to