2011-03-17 5 views
5

मुझे पाइथन में एक स्थिर विधि को सजाने में एक छोटी सी समस्या है। मुझे लगता है कि निम्नलिखित कोड मेरी समस्या का सबसे अच्छा प्रतिनिधित्व करता है:पायथन: सजाए गए staticmethod गैर कॉल करने योग्य विधि प्राप्त करता है

def decorator(func): 
    print callable(func) 
    return func 

class Foo(): 
    @decorator 
    @staticmethod 
    def bar(): 
     return 

# outputs False 

print callable(Foo.bar) 
# outputs True 

यह एक बग प्रतीत होता है। मुझे लगता है कि यह उठता है क्योंकि जब विधि Foo.bar सजावटी को पास की जाती है, तो यह एक कार्य है, एक विधि नहीं। यही कारण है कि मैं इसे कॉल करने योग्य नहीं देख सकता, क्योंकि यदि हम एक मानक कार्य को सजाने के लिए कहते हैं, तो यह कॉल करने योग्य नहीं है, जैसा कि नीचे दिखाया गया है।

@staticmethod 
def function(): 
    return 

print callable(function) 
# outputs False 

तो यह staticmethod डेकोरेटर के कार्यान्वयन में एक सच्चे बग है, और/या वहाँ किसी भी साधारण कामकाज से जुड़े हैं? मैंने __call__ विशेषता को एग्ग्न करने के लिए एक सजावट लिखने के बारे में सोचा था, लेकिन मुझे नहीं पता कि callable लागू किया गया है, इसलिए मैं इस तरह की विधि की आवश्यकता को गेज नहीं कर सकता।

+0

ध्यान दें कि आपको 'staticmethod' के लिए नए-शैली वर्गों का उपयोग उदाहरणों पर भी कॉल करने योग्य होना चाहिए, क्योंकि यह वर्णनकर्ताओं का उपयोग करता है। –

+2

इसे काम करने के लिए, बस वर्णनकर्ताओं के क्रम को बदलें। –

उत्तर

4

तरीके फ़ंक्शन हैं। लेकिन staticmethod वस्तुओं नहीं हैं। वे descriptors हैं, इसलिए अतिरिक्त जादू है जो आपको Cls.static_method के रूप में एक्सेस करते समय कॉल करने योग्य बनाता है, लेकिन जब आप Cls के शरीर के अंदर उपयोग करते हैं तो यह जादू कुछ भी छिपा नहीं सकता है (यानी सजावट करने के लिए पास) static_method। आप वास्तव में कम से कम साफ नहीं, इसके आसपास अपने रास्ते को वास्तव में हैक नहीं कर सकते हैं। एक बहुत ही सरल समाधान सजावटीों को फिर से व्यवस्थित कर रहा है जैसे कि staticmethod अंतिम लागू हो जाएं - यानी इसे अन्य सभी सजावट के ऊपर, शीर्ष पर रखें।

+0

आह जो समझ में आता है। धन्यवाद। –

4

ठीक है, कि क्या आप यह एक बग नहीं करने पर विचार या, यह documented है:

स्टेटिक विधि वस्तुओं विधि के लिए समारोह वस्तुओं के परिवर्तन को हराने का एक तरीका वस्तुओं प्रदान ऊपर वर्णित है। एक स्थिर विधि ऑब्जेक्ट किसी अन्य ऑब्जेक्ट के आसपास एक रैपर है, आमतौर पर उपयोगकर्ता द्वारा परिभाषित विधि ऑब्जेक्ट। जब एक स्थिर विधि ऑब्जेक्ट किसी कक्षा या कक्षा उदाहरण से पुनर्प्राप्त किया गया है, तो ऑब्जेक्ट वास्तव में वापस आ गया है, जो किसी और परिवर्तन के अधीन नहीं है। स्टेटिक विधि ऑब्जेक्ट स्वयं कॉल करने योग्य नहीं हैं, हालांकि ऑब्जेक्ट्स वे आमतौर पर लपेटते हैं। स्टेटिक विधि ऑब्जेक्ट अंतर्निहित staticmethod() कन्स्ट्रक्टर द्वारा बनाए जाते हैं।

0

मैंने staticmethod का अपना कार्यान्वयन लिखा है कि कॉल करने योग्य है और ऐसा लगता है कि यह समस्या अच्छी तरह से हल हो रही है।

class staticmethod(object): 
    """Make @staticmethods play nice with @memoize.""" 

    def __init__(self, func): 
     self.func = func 

    def __call__(self, *args, **kwargs): 
     """Call the static method with no instance.""" 
     return self.func(*args, **kwargs) 

यह वर्णनकर्ता प्रोटोकॉल का उपयोग नहीं करता है और इस तरह बर्ताव करता है बहुत अलग ढंग से निर्मित staticmethod आंतरिक रूप के रूप में, लेकिन व्यवहार में यह प्रतिदेय कार्यों वर्ग विशेषताओं के रूप में करता है, उदाहरण के गुण, और समारोह विशेषताओं के रूप में भी (यानी, अगर आपने अपनी कक्षा को सजावटी समारोह में लपेट लिया है, staticmethod के इस कार्यान्वयन से आप अभी भी अपनी स्थिर विधियों को रैपिंग फ़ंक्शन पर विशेषताओं के रूप में कॉल करने की अनुमति देंगे)।

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