2013-10-07 5 views
10

टी एल; डॉ मैं कैसे पता लगाएँ कि क्या एक समारोह में एक ही प्रभाव के साथ @classmethod या कुछ का उपयोग कर परिभाषित किया गया था लगता है?चेक एक समारोह @classmethod का उपयोग करता है, तो


मेरे समस्या

एक वर्ग डेकोरेटर को लागू करने के लिए मैं एक विधि, उदाहरण के लिए के रूप में के माध्यम से

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

मैंने पाया हासिल की अपनी पहली तर्क के रूप में वर्ग लेता है, तो जाँच करने के लिए चाहते हैं मॉड्यूल के माध्यम से @staticmethod के लिए जांच करने का एक समाधान (isinstance(foo, types.UnboundMethodType)False है यदि foo स्थिर है, तो here देखें), लेकिन कैसे के लिए @classmethod


प्रसंग

ऐसा करने के लिए पर कुछ भी नहीं मिला मुझे क्या करना कोशिश कर रहा हूँ

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 

और मैं करता हूँ की तर्ज पर कुछ है इस उदाहरण में isclassmethod को लागू करने के बारे में नहीं पता कि

उत्तर

15

अजगर 2 के लिए, आप परीक्षण की आवश्यकता दोनों अगर वस्तु (नियमित तरीकों के लिए एक विधि, और कक्षा में__self__ अगर अंक है यह None जब से लिया गया हो जाएगा कक्षा):

>>> 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 

पायथन 3 में, नियमित तरीके कार्य के रूप में दिखाई देते हैं (अनबाउंड विधियों को समाप्त कर दिया गया है)।

दोनों अजगर 2 और 3 में एक वर्ग विधि का पता लगाने के एक असफल-सुरक्षित विधि के लिए inspect.ismethod() के साथ इस संयुक्त करें:

import inspect 

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

method.__self__ विशेषता अजगर 2.6 में जोड़ा गया है एक समान होना चाहिए अजगर 3. साथ अजगर में 2.6 और 2.7 यह method.im_self का उपनाम है।

5

आपकोका उपयोग करना चाहिए। यह काम करता है क्योंकि classmethod फ़ंक्शन को क्लास ऑब्जेक्ट से जोड़ता है। निम्नलिखित कोड देखें:

>>> 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

यह केवल पायथन 3 –

+1

के लिए सच है क्या पाइथन 2 और पायथन 3 (व्यक्तिगत रूप से, मैं 2.7 का उपयोग करता हूं) के लिए कुछ भी काम कर रहा हूं। – hlt

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

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

यह मेरे लिए काम करता है:

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

यह मूल रूप से परीक्षण करता है, तो method.__self__ मौजूद है और मार्टिन के जवाब के रूप में, एक वर्ग है, लेकिन कक्षा में ही करने के लिए उपयोग की आवश्यकता नहीं है।

संबंधित मुद्दे