Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How is a staticmethod not bound to to the "staticmethod" class?

I'm trying to understand how descriptors work in python. I got the big picture, but I have problems understanding the @staticmethod decorator.

The code I'm referring to specifically is from the corresponding python doc: https://docs.python.org/3/howto/descriptor.html

class Function(object):
    . . .
    def __get__(self, obj, objtype=None):
        "Simulate func_descr_get() in Objects/funcobject.c"
        if obj is None:
            return self
        return types.MethodType(self, obj)
class StaticMethod(object):
    "Emulate PyStaticMethod_Type() in Objects/funcobject.c"

    def __init__(self, f):
        self.f = f

    def __get__(self, obj, objtype=None):
        return self.f

My question is: When self.f is accessed in the last line, doesn't f get recognized as a descriptor itself (because every function is a non-data descriptor) and thus gets bound to self, which is a StaticMethod object?

like image 601
zumgruenenbaum Avatar asked Nov 01 '19 12:11

zumgruenenbaum


People also ask

What's the point of Staticmethod?

Static methods can be used to group similar utility methods under the same class. For methods within a class, you either need to add self as the first argument or decorate the method with @staticmethod . "Non-decorated methods" without arguments will raise an error.

What is the difference between @classmethod and Staticmethod?

Class method can access and modify the class state. Static Method cannot access or modify the class state. The class method takes the class as parameter to know about the state of that class. Static methods do not know about class state.

How do you call a static method from a class?

A static method can be called from either a class or object reference. We can call it Utils if foo() is a static function in Class Utils. Utils. foo() as well as Utils().

What is the point of Classmethod Python?

A class method is a method which is bound to the class and not the object of the class. They have the access to the state of the class as it takes a class parameter that points to the class and not the object instance. It can modify a class state that would apply across all the instances of the class.


1 Answers

Descriptors are class attributes and hence need to be defined at the class level.

The function f in the last example is an instance attribute, as set inside __init__ by binding to attribute named f to the input object referred by f. As it is not a class attribute, it will never be classified as a descriptor.


Now, from the caller's perspective, staticmethod is a class attribute as it is implemented at the class level e.g. like:

class Foo:
    @staticmethod
    def bar():
        return 10

the decorator is only a syntactic sugar, you can very well write like:

class Foo:
    def bar():
        return 10
    bar = staticmethod(bar)

so it will be treated as a descriptor in this case.

like image 170
heemayl Avatar answered Oct 23 '22 02:10

heemayl