2012-02-12 15 views
7

ここで、デコレータのクラスメソッドのソースコードは、Pythonのソースコードにあります。しかし、以下のピュアPythonで書かれたclassmethodと同等デコレータ、何ができるかを示す - - ので、具体的に私は、私はあなたが尋ね答えていないのですトラブルそれはバージョン2.7.2@classmethodの場所

答えて

11

で定義されています正確なファイルを見つけることが生じていますソースコード中の1つはCで、0123はMishnaが彼の答えを入れているように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'> 
>>> 

* EDIT - 更新*

さらにO.P.は、「デコレータがinitを適切な形式にするためにパラメータを受け入れることを欲したのですか? " -

この場合、変更する必要があるのは__init__だけです - 設定パラメータを受け入れるデコレータは実際には" 2段階 "で呼び出されます - 最初のパラメータはパラメータに注釈を付け、呼び出し可能なものを返します - 実際に飾られる機能のみを受け付け

あり、それを行うには、いくつかの方法がある - しかし、私はのように最も簡単には、上記のクラスを返す関数を持つことだと思う:。

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

私はデコレータがパラを受け入れることを望むなら何が正しいinitのフォーマットでしょうか? – user1200501

+0

\\ \ get \ _ \ _の代わりに\ _ \ _呼び出し\ _ \ _を使用できますか? – DiogoNeves

+0

OK、ディスクリプタについて少し読んだら、今それは意味があります:) – DiogoNeves

9
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 */ 
... 
+0

おかげでクラスの正しい場所のために – user1200501