[Tutor] Difference(s) betweenPython 3 static methods with and without @staticmethod?

eryk sun eryksun at gmail.com
Sun Aug 6 20:43:06 EDT 2017


On Sun, Aug 6, 2017 at 11:35 PM, boB Stepp <robertvstepp at gmail.com> wrote:
>
> I see no difference in result, whether I use the @staticmethod decorator or not.

While a staticmethod and a function are both descriptors [1], a
staticmethod is basically a no-op descriptor. Its __get__ method
always returns its unbound callable (i.e. its __func__ attribute)
instead of returning a computed property or bound method.

Examples

    >>> descr = vars(MyOtherClass)['my_other_method']
    >>> descr
    <staticmethod object at 0x7f558d7846d8>

    >>> descr.__func__
    <function MyOtherClass.my_other_method at 0x7f558d7859d8>

When accessed as an attribute of a class (i.e. the instance argument
passed to __get__ is None), a staticmethod returns just its __func__.

    >>> descr.__get__(None, MyOtherClass)
    <function MyOtherClass.my_other_method at 0x7f558d7859d8>

That's effectively no different from a Python 3 function. But they
diverge when accessed as an attribute of an instance. In this case the
__get__ method of a staticmethod also simply returns its __func__,

    >>> descr.__get__(MyOtherClass(), MyOtherClass)
    <function MyOtherClass.my_other_method at 0x7f558d7859d8>

whereas the __get__ method of a function returns a method that's bound
to the instance.

    >>> func = vars(MyClass)['my_method']
    >>> func
    <function MyClass.my_method at 0x7f558d7858c8>

    >>> func.__get__(MyClass(), MyClass)
    <bound method MyClass.my_method of
        <__main__.MyClass object at 0x7f558d7847f0>>

[1]: https://docs.python.org/3/reference/datamodel.html#implementing-descriptors


More information about the Tutor mailing list