2009-06-29 13 views
41

पाइथन मॉड्यूल को __call__ क्यों नहीं देता है? (स्पष्ट है कि यह सीधे आयात करना आसान नहीं होगा।) विशेष रूप से, a(b) सिंटैक्स का उपयोग क्यों नहीं करता है __call__ विशेषताएँ जैसे कार्यों, वर्गों और वस्तुओं के लिए करता है? (देखने सिर्फ मॉड्यूल के लिए incompatibly अलग है?)कॉल करने योग्य मॉड्यूल

>>> print open("mod_call.py").read() 
def __call__(): 
    return 42 

>>> import mod_call 
>>> mod_call() 
Traceback (most recent call last): 
    File "<stdin>", line 1, in <module> 
TypeError: 'module' object is not callable 
>>> mod_call.__call__() 
42 
+0

एक पैकेजर से अपने स्वयं के उप-मॉड्यूल में एक सजावटी को माइग्रेट करना। @example (...) अब तक का सबसे आम उपयोग-मामला था, लेकिन @ example.special_case (...) एक नया उपयोग था। मैं इसे एक उदाहरण वर्ग और स्थैतिक तरीकों से लागू नहीं करना चाहता था, क्योंकि यह एक खराब फिट था। सुनिश्चित नहीं है कि एक कॉल करने योग्य मॉड्यूल बेहतर फिट है, लेकिन मैंने इसकी जांच शुरू कर दी और फिर जानना चाहता था कि यह क्यों काम नहीं कर रहा था। –

+3

मैंने यह भी सोचा था कि यह मॉड्यूल बनाकर डेटाटाइम और दशमलव जैसे कुछ मॉड्यूल को सरल बना सकता है .__ call__ क्रमशः डेटाटाइम या दशमलव हो। क्रमशः दशमलव। हालांकि, फिर टाइप करें (दशमलव ('1')) दशमलव के समान नहीं होगा, और संभव अन्य समस्याएं। * शग * यह एक विचार था। –

+0

"स्पष्ट है कि सीधे आयात करना आसान नहीं होगा।" आप ऐसा क्यों सोचते हैं? –

उत्तर

29

विशेष तरीकों केवल परोक्ष के नाम से जाना जब वे उदाहरण पर नहीं, प्रकार पर परिभाषित कर रहे हैं की गारंटी है। (__call__ मॉड्यूल उदाहरण mod_call की विशेषता है, <type 'module'> नहीं।) आप अंतर्निहित प्रकारों के तरीकों को जोड़ नहीं सकते हैं।

http://docs.python.org/reference/datamodel.html#special-method-lookup-for-new-style-classes

+0

यह मेरे लिए सही सही उत्तर की तरह लगता है! पक्षियों से परिप्रेक्ष्य देखें यह पाइथन में एक डिजाइन दोष की तरह दिखता है। क्या एक और डिजाइन आंतरिक रूप से मुश्किल या असंभव होगा? – jolvi

75

पायथन मॉड्यूल रखते हुए, सरल नियमित वस्तुओं और हल्के कैसे शायद ही कभी मजबूत उपयोग के मामलों जहां जादू इस्तेमाल कर सकते हैं दिखाई देते हैं पर विचार अभी भी फायदेमंद है क्योंकि, मॉड्यूल ओवरराइड या किसी जादू विधि जोड़ने के लिए अनुमति नहीं है वहां विधियां

जब ऐसे उपयोग के मामले प्रकट होते हैं, तो समाधान एक क्लास इंस्टेंस को मॉड्यूल के रूप में मास्कराइड करना है। इस प्रकार विशेष रूप से, अपने mod_call.py कोड:

import sys 
class mod_call(object): 
    def __call__(self): 
    return 42 
sys.modules[__name__] = mod_call() 

अब आप अपने कोड के आयात और mod_call बुला ठीक काम करता है।

+1

वाह। मैं आपके उदाहरण के आधार पर कोड उदाहरण पोस्ट करने से कुछ सेकंड था: http://stackoverflow.com/questions/880530/can-python-modules-have-properties-the-same-way-that-objects-can/880550 # 880550 – Stephan202

+2

हे, एसओ कभी-कभी प्रतिबिंबों की एक परीक्षा की तरह लगता है! -) –

+0

परिप्रेक्ष्य, एलेक्स के लिए धन्यवाद। – gahooa

2

जैसा कि माइल्स कहते हैं, आपको कक्षा स्तर पर कॉल को परिभाषित करने की आवश्यकता है। तो एलेक्स पोस्ट का विकल्प sys.modules[__name__] की श्रेणी को sys.modules[__name__] के प्रकार के उप-वर्ग में बदलना है (यह types.ModuleType होना चाहिए)।

इसका लाभ यह है कि मॉड्यूल के सभी अन्य गुणों को रखने के दौरान मॉड्यूल कॉल करने योग्य है (जैसे कार्य, चर, ...)।

import sys 

class MyModule(sys.modules[__name__].__class__): 
    def __call__(self): # module callable 
     return 42 

sys.modules[__name__].__class__ = MyModule 

नोट: पायथन 3.6 के साथ परीक्षण किया गया।

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