38

At what point do methods in Python acquire a get property? —As soon as they're defined in the class? Why does Python let me define a method without any arguments (not even a first self argument)?

I know how to use classmethod and staticmethod, and I know that they're built-in functions, but what happens to a function that is so-decorated?

Essentially, I'm wondering about the "magic" that happens between class definition and class construction.

2 Answers 2

35

Check this out.

https://docs.python.org/3/howto/descriptor.html#class-methods

You can also take a look at the source code for class and static method objects, in funcobject.c:

http://hg.python.org/cpython/file/69b416cd1727/Objects/funcobject.c

Class method object definition starts on line 694, while static method object definition starts on line 852. (I do find it kind of funny that they have items titled "method" in funcobject.c when methodobject.c also exists.)

Sign up to request clarification or add additional context in comments.

6 Comments

The #reference on that link is now 404 so you may want to follow: docs.python.org/3/howto/descriptor.html#class-methods instead
I would really appreciate an explanation and walk-through here of the class ClassMethod: implementation of "Emulate PyClassMethod_Type() in Objects/funcobject.c" found at docs.python.org/3/howto/descriptor.html#class-methods
@NeilG Thanks for the heads up. What particularly are you confused about with the pure Python version?
@NeilG Basically, types.FunctionType.__get__ is defined to implement instance methods. classmethod and staticmethod just provide suitable definitions of __get__ to implement class- and static-method behavior, respectively. (For example, staticmethod.__get__ always returns the underlying function instead of a method object.)
Thanks @chepner - I'm a lot clearer now on this and since the question was asked Python has changed the underlying process, but that's a good way of thinking about it. The funny thing that I just realised though, is that the "Neil G" who asked the question is not me! No wonder I couldn't remember asking the question! Lol :-D
|
15

For reference, from the first link in @JAB's answer

Using the non-data descriptor protocol, a pure Python version of staticmethod() would look like this:

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

...

Using the non-data descriptor protocol, a pure Python version of classmethod() would look like this:

class ClassMethod(object):
    "Emulate PyClassMethod_Type() in Objects/funcobject.c"

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

    def __get__(self, obj, klass=None):
        if klass is None:
            klass = type(obj)
        def newfunc(*args):
            return self.f(klass, *args)
        return newfunc

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.