2012-08-06 22 views
11

पायथन में, मान लीजिए कि मेरे पास एक कार्य f है जो मैं कुछ माध्यमिक तर्कों के साथ पास करना चाहता हूं (सादगी के लिए मान लें कि यह केवल पहला तर्क है जो चर बना रहता है)।functools.partial और इसी तरह के लैम्ब्डा के बीच मतभेद?

इन दो तरीकों (यदि कोई हो) के बीच अंतर क्या हैं?

partial वस्तुओं की कक्षाओं में परिभाषित स्थिर तरीकों की तरह व्यवहार और उदाहरण दौरान बाध्य तरीकों में बदलना नहीं है देखो-अप विशेषता:

# Assume secondary_args and secondary_kwargs have been defined 

import functools 

g1 = functools.partial(f, *secondary_args, **secondary_kwargs) 
g2 = lambda x: f(x, *secondary_args, **secondary_kwargs) 

doc page for partial, उदाहरण के लिए, इस उद्धरण है।

क्या लैम्बडा-विधि कक्षा से आपूर्ति किए गए तर्कों से क्लास विधि बनाने के लिए उपयोग की जाती है (या तो कन्स्ट्रक्टर में या बाद में फ़ंक्शन के माध्यम से)?

+1

मुझे लगता है कि मेरा प्रश्न लिंक किए गए एक से अलग है, हालांकि उस प्रश्न का शीर्ष उत्तर इतना गहन है कि यह जो कुछ भी मैं ढूंढ रहा था उससे भी अधिक (संयोग से) जवाब देता है। यदि यह एक डुप्लिकेट के रूप में बंद है तो मैं शिकायत नहीं करूंगा। – ely

+0

मैं मानता हूं कि यह एक डुप्लिकेट नहीं है, मैंने आपका प्रश्न फिर से खोला है। अन्य संदर्भों के लिए, संबंधित प्रश्न [यहां] है (http://stackoverflow.com/questions/220658/what-is-the-difference-between-a-closure-and-a-lambda)। – wim

उत्तर

9
  1. एक लैम्ब्डा फ़ंक्शन एक मानक फ़ंक्शन के समान प्रकार है, इसलिए यह एक उदाहरण विधि की तरह व्यवहार करेगा।

  2. अपने उदाहरण में partial वस्तु इस तरह कहा जाता जा सकता है:

    g1(x, y, z) 
    

    इस कॉल के लिए अग्रणी (मान्य नहीं अजगर वाक्य रचना है, लेकिन आप अंदाजा हो):

    f(*secondary_args, x, y, z, **secondary_kwargs) 
    

    लैम्ब्डा केवल एक तर्क स्वीकार करता है और एक अलग तर्क आदेश का उपयोग करता है। (बेशक इन मतभेदों के दोनों पर काबू पाने जा सकता है - मैं तो बस का जवाब दे रहा हूँ क्या दो संस्करणों के बीच मतभेदों को आप कर रहे हैं दे दी है।) partial वस्तु की

  3. निष्पादन थोड़ा तेजी से बराबर lambda के निष्पादन की तुलना में है।

+0

क्या आपने 'lambda' की तुलना में 'आंशिक' ऑब्जेक्ट का प्रोफाइल किया है? – orlp

+2

@ रात्रिभोजक: हाँ, अभी नहीं, लेकिन अतीत में कई बार। 'आंशिक' ऑब्जेक्ट पाइथन कोड ऑब्जेक्ट नहीं बनाता है, इसलिए यह एक पूर्ण पायथन स्टैक फ्रेम बचाता है। –

+0

@ स्वेन मार्नच: और वास्तव में तेज़ क्या है, सृजन कोड, कॉलिंग कोड या दोनों? – orlp

0

मेरा मानना ​​है कि कक्षा विधि चीज केवल कक्षा परिभाषा के दौरान आवंटित कार्यों पर लागू होती है। बाद में कार्य किए गए कार्यों का विशेष रूप से इलाज नहीं किया जाता है।

इसके अलावा, मैं व्यक्तिगत रूप से लैम्बडा का पक्ष लेता हूं क्योंकि वे अधिक आम हैं और इसलिए कोड को समझना आसान हो जाता है।

class Foo(object): 
    def __init__(self, base): 
     self.int = lambda x:int(x, base) 

print Foo(4).int('11') 
+4

'मैं व्यक्तिगत रूप से लैम्बास का पक्ष लेता हूं क्योंकि वे अधिक आम हैं और इसलिए कोड को समझना आसान हो जाता है।' मैंने कभी इन बयानों में से कोई भी नहीं सुना है। – phant0m

+0

@ phant0m पाइथन लैम्बदास के बारे में मैंने जो अधिकांश बयान सुना है, उनमें शब्द 'टूटा हुआ' था। ;-) –

+0

@Chris functools.partial क्लीनर है, लेकिन मुझे लगता है कि जब तक आपके पास स्कोपिंग समस्या नहीं है तब तक लैम्ब्डा को समझना आसान होता है। एक बात के लिए, लैम्बडास का मतलब है कि आपको सटीक तर्क आदेश को याद रखना नहीं है जो functools.partial लेता है। – Antimony

0

हां, lambda इससे "पीड़ित" होगा। partial में यह समस्या नहीं है क्योंकि यह एक वास्तविक कार्य के बजाय, कॉल ऑपरेटर ओवरलोडेड वाला एक ऑब्जेक्ट है।

लेकिन कक्षा परिभाषा में इस तरह एक लैम्ब्डा का उपयोग करना सिर्फ दुरुपयोग है।

0

आंशिक केवल समकक्ष लैम्ब्डा से लगभग 20% तेज नहीं हैं जैसा कि पहले से ही कहा गया है लेकिन वे संबंधित कार्य करने के लिए सीधे रेफरी रखते हैं। जबकि लैम्ब्स में यह कार्य फ़ंक्शन बॉडी के भीतर 'burried' है।

=> यदि आपको केवल एक फ़ंक्शन के मूल्यांकन को रोकने की समस्या को हल करने की आवश्यकता है जब तक कि सभी तर्क ज्ञात न हों तब आंशिक उपयोग करें। गुमनाम कार्यों में कॉल को दफनाने की तुलना में आपके पास बेहतर आत्मनिरीक्षण विधियां होंगी, यानी lambdas।