2008-12-11 17 views
6

ऐसा करने का एक आसान तरीका होना चाहिए, लेकिन किसी भी तरह से मैं इसके चारों ओर अपने सिर को लपेट सकता हूं। मैं जो चाहता हूं उसका वर्णन करने का सबसे अच्छा तरीका एक वर्ग के लिए लैम्ब्डा फ़ंक्शन है। मेरे पास एक लाइब्रेरी है जो एक वर्ग के साथ काम करने के लिए एक वर्ग के एक uninstantiated संस्करण के रूप में उम्मीद है। इसके बाद कक्षा को स्वयं काम करने के लिए तत्काल बनाता है। समस्या यह है कि मैं लाइब्रेरी को पास करने के लिए कक्षा के संस्करणों को गतिशील रूप से बनाने में सक्षम होना चाहता हूं, लेकिन मुझे यह नहीं पता कि पुस्तकालय एक अनइंस्टेन्टेड संस्करण की अपेक्षा करता है।पायथन में कक्षाओं के लिए Lambda समारोह?

class Double: 
    def run(self,x): 
     return x*2 

class Triple: 
    def run(self,x): 
     return x*3 

class Multiply: 
    def __init__(self,mult): 
     self.mult = mult 
    def run(self,x): 
     return x*self.mult 

class Library: 
    def __init__(self,c): 
     self.c = c() 
    def Op(self,val): 
     return self.c.run(val) 

op1 = Double 
op2 = Triple 
#op3 = Multiply(5) 

lib1 = Library(op1) 
lib2 = Library(op2) 
#lib3 = Library(op3) 

print lib1.Op(2) 
print lib2.Op(2) 
#print lib3.Op(2) 

मैं, सामान्य गुणा वर्ग उपयोग नहीं कर सकते क्योंकि मैं इसे पहले दृष्टांत चाहिए जो पुस्तकालय टूट जाता है "AttributeError: गुणा उदाहरण नहीं कॉल विधि है" नीचे कोड समस्या का वर्णन है। पुस्तकालय वर्ग को बदलने के बिना, क्या मैं ऐसा कर सकता हूं?

उत्तर

8

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

class Double: 
     def run(self,x): 
      return x*2 

class Triple: 
    def run(self,x): 
     return x*3 

def createMultiplier(n): 
    class Multiply: 
     def run(self,x): 
      return x*n 
    return Multiply 

class Library: 
    def __init__(self,c): 
     self.c = c() 
    def Op(self,val): 
     return self.c.run(val) 

op1 = Double 
op2 = Triple 
op3 = createMultiplier(5) 

lib1 = Library(op1) 
lib2 = Library(op2) 
lib3 = Library(op3) 

print lib1.Op(2) 
print lib2.Op(2) 
print lib3.Op(2) 
+0

एक सामान्य कनवर्टर का उपयोग कर, ज़ाहिर है, यह है कि यह सिद्धांत रूप में स्वीकार करेंगे किसी भी एक-आर्ग समारोह, स्पष्ट रूप से अपनी कक्षाओं –

+0

मैं createMultiplier() फंक्शन की तरह परिभाषित करने के लिए की आवश्यकता होगी, से आगे कार्यान्वयन को मुक्त है का लाभ। सुरुचिपूर्ण। – Deestan

+0

मुझे पता है कि यह एक पुरानी पोस्ट है, लेकिन यहां कुछ ध्यान देने योग्य है। createMultiplier (4)! = createMultiplier (4)। ऐसा इसलिए है क्योंकि कक्षा दो अलग-अलग मेमोरी स्थानों में दो बार बनाई गई है।जब तक मल्टीप्ली में मेटाक्लास नहीं होता है जो कक्षाओं की तुलना करने के लिए डिफ़ॉल्ट व्यवहार को ओवरराइड करता है, तो आपको उत्पादित वर्ग ऑब्जेक्ट को कैश करने के लिए एक सरल शब्दकोश बनाना चाहिए। निर्देश एन द्वारा की जाएगी, और मूल्य कक्षाएं होगी। लेकिन यदि कक्षाओं का एक समूह बनाया जाता है लेकिन अप्रयुक्त होता है तो यह स्मृति कुशल नहीं हो सकता है। गुणा करने के लिए कक्षा विशेषता को संलग्न करना सबसे आसान तरीका है। जैसे Multiply.x = 5। –

1

इस धोखाधड़ी की तरह है, लेकिन आप अपने गुणा वर्ग एक __call__ विधि है जो अपने आप रिटर्न दे सकता है: जब पुस्तकालय कॉल c() यह वास्तव में c.__call__() जो वस्तु आप चाहते हैं देता है कॉल

class Multiply: 
    def __init__(self,mult): 
     self.mult = mult 
    def __call__(self): 
     return self 
    def run(self,x): 
     return x*self.mult 

इस तरह।

1
def mult(x): 
    def f(): 
     return Multiply(x) 
    return f 


op3 = mult(5) 
lib3 = Library(op3) 
print lib3.Op(2) 
11

क्या लाइब्रेरी वास्तव में निर्दिष्ट करती है कि यह एक "प्रारंभिक संस्करण" (यानी एक वर्ग संदर्भ) चाहता है?

ऐसा लगता है कि पुस्तकालय वास्तव में एक वस्तु कारखाना चाहता है। उस मामले में, यह टाइप करने के लिए स्वीकार्य है:

Multiply5 = lambda: Multiply(5) 
assert Multiply5().run(3) == Multiply(5).run(3) 
1

मैं आपकी समस्या को अंतरिक्ष सही ढंग से समझ है, तो आप एक सामान्य इंटरफ़ेस 1 लेता है:

lib3 = Library(lambda: Multiply(5)) 

को समझने के लिए कैसे लैम्ब्डा काम करता है, निम्नलिखित पर विचार तर्क जिसे Library वर्ग का उपयोग करके बुलाया जाता है। दुर्भाग्यवश, फ़ंक्शन को कॉल करने के बजाय, Library मानता है कि फ़ंक्शन को कक्षा में run विधि के साथ लपेटा गया है।

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

def make_op(f): 
    class MyOp(object): 
    def run(self, x): 
     return f(x) 
    return MyOp 

op1 = make_op(lambda x: return x*2) 
op2 = make_op(lambda x: return x*3) 

def multiply_op(y): 
    return make_op(lambda x: return x*y) 

op3 = multiply_op(3) 

lib1 = Library(op1) 
lib2 = Library(op2) 
lib3 = Library(op3) 

print(lib1.Op(2)) 
print(lib2.Op(2)) 
print(lib3.Op(2)) 

कहा जा रहा है, लाइब्रेरी को बदलने एक समारोह लेने के लिए और फिर कार्यों प्रदान शायद मजबूत तरीका यह है है।

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