2013-01-06 8 views
5

समान प्रश्न (को Python2 के साथ संबंधित: Python: check if method is static)python3: जाँच करता है, तो विधि स्थिर है

वर्ग परिभाषा निम्नलिखित पर विचार करने देता है:

class A: 
    def f(self): 
    return 'this is f' 

    @staticmethod 
    def g(): 
    return 'this is g' 

अजगर 3 में नहीं है अब और कोई instancemethod, सब कुछ समारोह है, इसलिए पायथन 2 से संबंधित जवाब अब और काम नहीं करेगा।

जैसा कि मैंने कहा था, सब कुछ समारोह है, इसलिए हम A.f(0) कॉल कर सकते हैं, लेकिन निश्चित रूप से हम कॉल नहीं कर सकते A.f() (तर्क missmatch)। लेकिन अगर हम a=A() उदाहरण देते हैं और हम a.f() पर कॉल करते हैं तो पाइथन A.fself को पहले तर्क के रूप में कार्य करता है। कॉलिंग a.g() इसे भेजने या self पर कैप्चर करने से रोकती है - इसलिए यह जांचने का एक तरीका होना चाहिए कि यह staticmethod है या नहीं।

तो क्या हम static के रूप में घोषित किए जाने पर पाइथन 3 में जांच सकते हैं या नहीं?

+0

मैं पूछ सकता हूँ क्यों तुम यह करने के लिए कोशिश कर रहे हैं उत्तर के आधार पर निम्नलिखित? –

+1

बेशक, मैं अपना खुद का प्लगइन ढांचा बना रहा हूं और मैं कुछ इंटरफ़ेस घोषणाओं का निरीक्षण करना चाहता हूं और मुझे यह जानना अच्छा लगेगा कि कुछ staticmethod के रूप में घोषित किया गया था या नहीं :) –

उत्तर

8
class A: 
    def f(self): 
    return 'this is f' 

    @staticmethod 
    def g(): 
    return 'this is g' 
print(type(A.__dict__['g'])) 
print(type(A.g)) 

<class 'staticmethod'> 
<class 'function'> 
+0

बढ़िया! क्या आप कृपया यह भी समझा सकते हैं कि 'ए .__ dict __ [' g '] ''.g' से कुछ और क्यों देता है? –

+5

'ए .__ dict __ ['g']' '.g} से अलग है क्योंकि फ़ंक्शन [descriptors] (http://docs.python.org/2/reference/datamodel.html#descriptors) हैं। फंक्शन ऑब्जेक्ट्स डिस्क्रिप्टर हैं क्योंकि वे '__get__' विधि को परिभाषित करते हैं, जिसे ऑब्जेक्ट को डॉट नोटेशन (जैसे' एएफ') का उपयोग करके एक्सेस किया जाता है। वर्णनकर्ता प्रोटोकॉल यह है कि कैसे (उदाहरण के लिए) एक उदाहरण पर कॉल किए जाने पर _function_ को _bound method_ में बदल दिया जाता है। डॉट नोटेशन का उपयोग करने के बजाय '__dict__' के माध्यम से जाकर, वर्णनकर्ता प्रोटोकॉल को छोड़ देता है। –

1

मैं इस समाधान की जरूरत है और लिखा से @root

def is_method_static(cls, method_name): 
    # http://stackoverflow.com/questions/14187973/python3-check-if-method-is-static 
    for c in cls.mro(): 
     if method_name in c.__dict__: 
      return isinstance(c.__dict__[method_name], staticmethod) 
    raise RuntimeError("Unable to find %s in %s" % (method_name, cls.__name__)) 
+0

यह केवल स्थिर विधियों के लिए काम करेगा जो विरासत में नहीं हैं। यदि आप विरासत में स्थिर विधियों का समर्थन करना चाहते हैं तो आप '__dict__' तक सीधे पहुंचने के बजाय' inspect.getattr_static' का उपयोग कर सकते हैं। –

+0

धन्यवाद, getattr_static 3.2 में नया है। मेरा कोड पाइथन 2 और पायथन 3 दोनों में चलता है –

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