位于python源代码中的decorator classmethod的源代码在哪里。具体来说,我无法找到它在2.7.2版本中定义的确切文件
答案 0 :(得分:17)
我没有回答你的问题 - 但是下面显示了用纯Python编写的等同于classmethod
的装饰器 - 因为源代码中的那个是在C中,在Python-2.7.2/Objects/funcobject.c
内米什纳提出了他的答案。
因此,类方法的想法是使用“描述符”机制,如Python's data model中所述 - 并使其成为__get__
方法返回一个函数对象,当被调用时,将使用预先填充的第一个参数调用原始方法:
class myclassmethod(object):
def __init__(self, method):
self.method = method
def __get__(self, instance, cls):
return lambda *args, **kw: self.method(cls, *args, **kw)
在Python控制台上:
>>> class MyClass(object):
... @myclassmethod
... def method(cls):
... print cls
...
>>>
>>> m = MyClass()
>>> m.method()
<class '__main__.MyClass'>
>>>
*编辑 - 更新*
O.P.进一步询问“如果我希望装饰者也接受一个参数,那么初始化的格式是什么?” -
在这种情况下,不仅需要更改__init__
- 接受配置参数的装饰器实际上是在“两个阶段”中调用的 - 第一个是注释参数,并返回一个可调用的 - 第二个call只接受实际装饰的功能。
有几种方法可以做到 - 但我认为最简单的方法是使用一个返回上面类的函数,如:
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
答案 1 :(得分:12)
tar -zxf Python-2.7.2.tgz
vim Python-2.7.2/Objects/funcobject.c
...
589 /* Class method object */
590
591 /* A class method receives the class as implicit first argument,
592 just like an instance method receives the instance.
593 To declare a class method, use this idiom:
594
595 class C:
596 def f(cls, arg1, arg2, ...): ...
597 f = classmethod(f)
598
599 It can be called either on the class (e.g. C.f()) or on an instance
600 (e.g. C().f()); the instance is ignored except for its class.
601 If a class method is called for a derived class, the derived class
602 object is passed as the implied first argument.
603
604 Class methods are different than C++ or Java static methods.
605 If you want those, see static methods below.
606 */
...