2013-10-07 27 views
10

TL Bir fonksiyonun @classmethod veya aynı etkiye sahip bir şey kullanılarak tanımlanıp tanımlanmadığını nasıl öğrenebilirim?Bir fonksiyonun @classmethod kullanıp kullanmadığını kontrol edin


bir sınıf dekoratör uygulanması için Sorunum

ben buldum

@classmethod 
def function(cls, ...): 

yoluyla elde gibi bir yöntem örneğin, ilk argüman olarak sınıf alır olmadığını kontrol etmek istiyorum @staticmethod'u modülü üzerinden kontrol etmek için bir çözüm (FalseFalse ise, bkz. here), Ancak @classmethod


Bağlamında

için bunun nasıl bir şey bulamadık Ne yapmaya çalışıyorum

def class_decorator(cls): 
    for member in cls.__dict__: 
     if (isclassmethod(getattr(cls, member))): 
      # do something with the method 
      setattr(cls, member, modified_method) 
    return cls 

ve yapmam çizgisinde bir şeydir Bu örnekte isclassmethod neyi aradığımı bilmiyorum.

cevap

15

Python 2 için, test etmemiz gerekiyor nesne düzenli yöntemler için (sınıfına bir yöntem ve__self__ eğer noktaları ise alınan zaman None olacak sınıfı):

>>> class Foo(object): 
...  @classmethod 
...  def bar(cls): 
...   pass 
...  def baz(self): 
...   pass 
... 
>>> Foo.baz 
<unbound method Foo.baz> 
>>> Foo.baz.__self__ 
>>> Foo.baz.__self__ is None 
True 
>>> Foo.bar.__self__ 
<class '__main__.Foo'> 
>>> Foo.bar.__self__ is Foo 
True 

Python 3, düzenli yöntemler ilişkisiz yöntemler uzağa ile yapılmıştır (fonksiyonları olarak gösterilir).

Python 2 ve 3'ün her ikisi de bir sınıf yöntemi tespit etmek için bir fail-güvenli bir metot ihtiyacı inspect.ismethod() ile birleştirin: method.__self__ özelliği Python 2.6 ilave edildi

import inspect 

if inspect.ismethod(cls.method) and cls.method.__self__ is cls: 
    # class method 

tutarlı olması için Python 3 ile Python'da 2.6 ve 2.7, method.im_self'un bir takma adıdır. method.__self__ var ve Martijn yanıtında olduğu gibi, bir sınıf ise

def is_classmethod(method): 
    """ 
    Is method a classmethod? 
    """ 
    return isinstance(getattr(method, '__self__', None), type) 

Temelde test eder ama sınıf kendisine erişim gerektirmez:

5

kullanmalısınız. Classmethod işlevi işlevi sınıf nesnesine bağladığı için çalışır. Aşağıdaki kodu bakınız:

>>> class Foo: 
...  @classmethod 
...  def bar(): 
...    pass 
...  def baz(): 
...    pass 
... 
>>> Foo.bar 
<bound method type.bar of <class '__main__.Foo'>> 
>>> Foo.baz 
<function Foo.baz at 0x0000000002CCC1E0> 
>>> type(Foo.bar) 
<class 'method'> 
>>> type(Foo.baz) 
<class 'function'> 
>>> import inspect 
>>> inspect.ismethod(Foo.bar) 
True 
>>> inspect.ismethod(Foo.baz) 
False 
+5

Bu yalnızca Python 3 için geçerli –

+1

Hem Python 2 hem de Python 3 için çalışan herhangi bir şey var mı (kişisel olarak, 2.7 kullanıyorum) – hlt

2
class Foo(object): 
    @classmethod 
    def baaz(cls): 
     print "baaz" 

isinstance(Foo.__dict__["baaz"], classmethod) 
0

Bu benim için çalışıyor.

İlgili konular