user1200501 user1200501 - 6 months ago 20
Python Question

Location of @classmethod

Where is the source code for the decorator classmethod located in the python source code. Specifically I am having trouble finding the exact file it's defined in version 2.7.2

Answer

I am not answering what you asked - but bellow goes what could be a decorator equivalent to classmethod, written in Pure Python - since the one in the source code is in C, inside Python-2.7.2/Objects/funcobject.c as Mishna puts in his answer.

So, the idea of class methods is to use the "descriptor" mechanism, as described in Python's data model - and make it so that the __get__ method does return a function object that when called, will call the original method with the first argument pre-filled:

class myclassmethod(object):
    def __init__(self, method):
        self.method = method
    def __get__(self, instance, cls):
        return lambda *args, **kw: self.method(cls, *args, **kw)

And on Python console:

>>> class MyClass(object):
...     @myclassmethod
...     def method(cls):
...         print cls
... 
>>> 
>>> m = MyClass()
>>> m.method()
<class '__main__.MyClass'>
>>> 

* EDIT - Update *

The O.P. further asked "If I wanted the decorator to also accept a parameter what would be the proper format for init? " -

In that case it is not only __init__ which has to be changed - a decorator that accepts configuration parameters is actually called in "two stages" - the first one annotate the parameters, and returns a callable - the second call accepts only the function which will actually be decorated.

There are a few ways to do it - but I think the most straightforward is to have a function that returns the class above, like in:

def myclasmethod(par1, par2, ...):
    class _myclassmethod(object):
        def __init__(self, method):
            self.method = method
        def __get__(self, instance, cls):
            # make use of par1, par2,... variables here at will
            return lambda *args, **kw: self.method(cls, *args, **kw)
    return _myclassmethod
Comments