2008-11-29 16 views
15

मैं अजगर में निम्न कार्य करने की कोशिश कर रहा हूँ:एक वर्ग वस्तु में अनबाउंड अजगर कार्यों भंडारण

एक फ़ाइल बुलाया foo.py में:

# simple function that does something: 
def myFunction(a,b,c): 
    print "call to myFunction:",a,b,c 

# class used to store some data: 
class data: 
    fn = None 

# assign function to the class for storage. 
data.fn = myFunction 

और फिर एक फ़ाइल बुलाया bar.py में :

: आयात foo

d = foo.data 
d.fn(1,2,3) 

हालांकि, मैं निम्नलिखित त्रुटि मिलती है 0

यह काफी उचित है मुझे लगता है - पायथन डी.मीफंक्शन को क्लास विधि के रूप में इलाज कर रहा है। हालांकि, मैं इसे सामान्य कार्य के रूप में मानना ​​चाहता हूं - इसलिए मैं इसे फ़ंक्शन परिभाषा में एक अप्रयुक्त 'स्वयं' पैरामीटर जोड़ने के बिना कॉल कर सकता हूं।

तो सवाल यह है:

मैं समारोह के बिना एक वर्ग वस्तु में एक समारोह कैसे स्टोर कर सकते हैं कि वर्ग के लिए बाध्य होता जा रहा?

+0

मुझे लगता है कि आप इसका उपयोग करना चाहते हैं: d.fn (1,2,3) और d.myFunctions (1,2,3) –

+0

हाँ, मुझे लगता है कि आपका मतलब डी.एफएन() – hop

+1

समाधान नीचे है, लेकिन आप यह क्यों चाहते हैं? – orip

उत्तर

23
data.fn = staticmethod(myFunction) 

चाल करना चाहिए।

+0

यह सही उत्तर और वाक्यविन्यास है, क्योंकि फ़ंक्शन को कहीं और परिभाषित किया गया है। – tzot

0

यह मेरे लिए व्यर्थ लगता है। जब आपको आवश्यकता हो तो मेरा फ़ंक्शन केवल कॉल क्यों न करें?

सामान्य तौर पर, पायथन में, हम नेमस्पेसिंग इस तरह की (जावा के साथ इस विपरीत जहां आप बस कोई विकल्प नहीं है) के लिए मॉड्यूल का उपयोग करें। और निश्चित रूप से, जब आप इसे परिभाषित करते हैं तो मेरा कार्य मॉड्यूल नेमस्पेस से पहले ही बाध्य है।

It is discussed somewhat in the answers to this question.

+0

मुझे लगता है कि आप किसी ऑब्जेक्ट को किसी विशेष फ़ंक्शन को अटैच कर सकते हैं, और उसके बाद इसे ऑब्जेक्ट द्वारा कॉल किया गया है, बिना किसी फ़ंक्शन को वास्तव में कॉल करना। –

+0

ओपी क्या कर रहा था, यह गलत समझा, यह नहीं देखा कि यह एक क्लास-विधि था उदाहरण-विधि नहीं। –

+0

आवश्यकता होने पर इसे कॉल करना बहुत अच्छा है - लेकिन परीक्षण करते समय, आप कॉलिंग फ़ंक्शन को मॉक करना चाहते हैं - यह उन कार्यों के साथ ट्रिकियर बन जाता है क्योंकि उनके दायरे को पकड़ना मुश्किल होता है। – Glycerine

1

आप क्या कर सकते है:

d = foo.data() 
d.fn = myFunction 

d.fn(1,2,3) 

कौन वास्तव में आप क्या चाहते हैं नहीं हो सकता है, लेकिन काम करता है।

0

उत्तर के लिए आंद्रे के लिए धन्यवाद - इतना आसान!

आप में से जो लोग परवाह के लिए, शायद मैं इस समस्या के पूरे संदर्भ को शामिल किया है चाहिए। यहां यह वैसे भी है:

मेरे आवेदन में, उपयोगकर्ता पाइथन में प्लगइन लिखने में सक्षम हैं। उन्हें एक अच्छी तरह परिभाषित पैरामीटर सूची के साथ एक फ़ंक्शन को परिभाषित करना होगा, लेकिन मैं उन पर किसी भी नामकरण सम्मेलन को लागू नहीं करना चाहता था।

# this is my custom code - all plugins are called with a modified sys.path, so this 
# imports some magic python code that defines the functions used below. 
from specialPluginHelperModule import * 

# define the function that does all the work in this plugin: 
def mySpecialFn(paramA, paramB, paramC): 
    # do some work here with the parameters above: 
    pass 

# set the above function: 
setPluginFunction(mySpecialFn) 

कॉल:

तो, जब तक उन मापदंडों और प्रकार की सही संख्या के साथ एक समारोह लिखते हैं, सब वे क्या करना है कुछ इस तरह (याद रखें, इस प्लगइन कोड है) setPluginFunction पर फ़ंक्शन ऑब्जेक्ट लेता है और इसे एक छिपे हुए क्लास ऑब्जेक्ट में सेट करता है (अन्य प्लगइन-कॉन्फ़िगरेशन से संबंधित सामग्री के साथ, यह उदाहरण कुछ हद तक सरलीकृत किया गया है)। जब मुख्य अनुप्रयोग फ़ंक्शन को चलाने के लिए चाहता है, तो मैं प्लगइन कोड चलाने के लिए runpy मॉड्यूल का उपयोग करता हूं, और उसके बाद उपरोक्त वर्णित क्लास ऑब्जेक्ट निकालें - यह मुझे कॉन्फ़िगरेशन डेटा और प्लगइन फ़ंक्शन देता है ताकि मैं इसे साफ़ रूप से चला सकूं (मेरे प्रदूषण के बिना नाम स्थान)।

इस संपूर्ण प्रक्रिया को एक ही इनपुट पर विभिन्न प्लगइन के लिए कई बार दोहराया जाता है, और ऐसा लगता है कि मेरे लिए बहुत अच्छा काम करता है।

+0

"सभी प्लगइन्स को एक संशोधित sys.path के साथ बुलाया जाता है" क्या आप sys.path को अस्थायी रूप से एक कोशिश/आखिरकार ब्लॉक में संशोधित कर रहे हैं या वैश्विक sys.path को "छाया" करने का कोई तरीका है? – haridsv

+4

अतिरिक्त जानकारी जोड़ने के लिए कृपया अपने प्रश्न पर संपादन लिंक का उपयोग करें। पोस्ट उत्तर बटन केवल प्रश्न के पूर्ण उत्तरों के लिए उपयोग किया जाना चाहिए। – cpburnz

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