2012-06-05 7 views
7

इन अलग व्यवहार ::कृपया बताएं कि इन दोनों में निर्मित कार्यों अलग व्यवहार करते हैं जब कीवर्ड तर्क में पारित

>> def minus(a, b): 
>> return a - b 

>> minus(**dict(b=2, a=1)) 
-1 

>> int(**dict(base=2, x='100')) 
4 

>> import operator 
>> operator.sub.__doc__ 
'sub(a, b) -- Same as a - b.' 
>> operator.sub(**dict(b=2, a=1)) 
TypeError: sub() takes no keyword arguments 

क्यों int(x, [base]) से अलग ढंग से operator.sub व्यवहार करता है पर विचार करें?

+3

यह अच्छा होगा अगर लोग यह भी जवाब दे सकें कि यह फ़ंक्शन कीवर्ड तर्कों का उपयोग न करने का कारण क्यों चुनता है, मैं इसे भी जानना चाहता हूं: डी – jamylak

उत्तर

7

यह एक कार्यान्वयन विस्तार है। Python C API to retrieve arguments स्थितित्मक और कीवर्ड तर्कों के बीच अलग करता है। स्थितित्मक तर्कों का आंतरिक रूप से नाम भी नहीं है।

PyArg_UnpackTuple(a,#OP,2,2,&a1,&a2) 

आप देख सकते हैं, यह किसी भी तर्क नाम शामिल नहीं है:

operator.add कार्य (और sub की तरह इसी तरह) के तर्कों को पुनः प्राप्त करने के लिए इस्तेमाल कोड यह है। पूरे operator.add से संबंधित कोड है:

#define spam2(OP,AOP) static PyObject *OP(PyObject *s, PyObject *a) { \ 
    PyObject *a1, *a2; \ 
    if(! PyArg_UnpackTuple(a,#OP,2,2,&a1,&a2)) return NULL; \ 
    return AOP(a1,a2); } 

spam2(op_add   , PyNumber_Add) 
#define spam2(OP,ALTOP,DOC) {#OP, op_##OP, METH_VARARGS, PyDoc_STR(DOC)}, \ 
          {#ALTOP, op_##OP, METH_VARARGS, PyDoc_STR(DOC)}, 
spam2(add,__add__, "add(a, b) -- Same as a + b.") 

आप देख सकते हैं, केवल जगह है जहाँ a और b उपयोग किया जाता है docstring में है। विधि परिभाषा METH_KEYWORDS ध्वज का भी उपयोग नहीं करती है जो कीवर्ड तर्कों को स्वीकार करने के तरीके के लिए आवश्यक होगी।

आम तौर पर बात की, आप सुरक्षित रूप से ग्रहण कर सकते हैं एक अजगर आधारित समारोह जहाँ आप जानते हैं एक तर्क नाम हमेशा कीवर्ड तर्क को स्वीकार करेंगे (निश्चित रूप से किसी को *args खोल लेकिन एक समारोह डॉक जहां तर्क देखो बनाने के साथ बुरा सामान कर सकता है कि सामान्य) जबकि सी फ़ंक्शन कीवर्ड तर्क स्वीकार कर सकते हैं या नहीं भी। संभावनाएं अच्छी हैं कि कुछ तर्कों या वैकल्पिक तर्कों के साथ कार्य करने वाले बाद के/वैकल्पिक लोगों के लिए कीवर्ड तर्क स्वीकार करते हैं। लेकिन आपको इसका परीक्षण करना बहुत अधिक है।

आप python-ideas mailinglist पर हर जगह कीवर्ड तर्कों का समर्थन करने के बारे में चर्चा कर सकते हैं।

हम्म: वहाँ भी उस पर गुइडो van Rossum से एक बयान (Benevolent Dictator For Life अजगर के निर्माता उर्फ) है। मुझे लगता है कि कई (सबसे?) 1-तर्क और चयनित 2-तर्क फ़ंक्शंस (और शायद ही कभी 3 + -र्ग फ़ंक्शन) हैं, इससे पठनीयता कम हो जाएगी, उदाहरण के उदाहरण ord (char = x) दिखाया गया है।

मैं वास्तव में राज्य के लिए है कि एक तर्क एक कीवर्ड तर्क (बस के रूप में हम पहले से ही राज्य के लिए है कि यह एक कीवर्ड होना चाहिए वाक्य रचना जोड़ा) के रूप में नहीं दिया जा सकता है एक वाक्यात्मक सुविधा को देखने के लिए चाहते हैं।

एक क्षेत्र जहां मुझे लगता है कि कीवर्ड तर्क जोड़ना गलत है: अंतर्निहित प्रकार या एबीसी के तरीके और यह अतिसंवेदनशील हैं। जैसे dict12 पर पॉप() विधि पर विचार करें।वर्तमान में अप्रलेखित, अगर कोई dict उपवर्गों और इस विधि को ओवरराइड करता है, या अगर वे एक और परिवर्तनशील मानचित्रण वर्ग बतख टाइपिंग का उपयोग कर dict का अनुकरण करने की कोशिश करता है कि बनाने के लिए, यह कोई बात नहीं के बाद से तर्क नाम है क्या तर्क नाम है - सभी कॉलर्स (एक निर्देश, एक dict subclass, या एक dict- जैसे बतख की उम्मीद) कॉल में स्थितित्मक तर्क का उपयोग करेंगे। लेकिन अगर हम पॉप() के लिए तर्क नाम दस्तावेज करने के लिए थे, और उपयोगकर्ताओं ने इन का उपयोग करना शुरू किया, तो अधिकांश निर्देश sublcasses और बतख अचानक तोड़ दिए जाएंगे (अगर भाग्य से वे एक ही नाम चुनते हैं)।

+0

+1 यह मेरा प्रश्न भी उत्तर देता है! – jamylak

+0

स्टाइलिस्ट पसंद से परे, मुझे यह इंगित करना चाहिए कि फ़ंक्शन कॉल में सभी जोड़ों के ऊपर कीवर्ड तर्क स्वीकार करना, और यदि उपयोगकर्ता वास्तव में कीवर्ड द्वारा अंतर्निहित तर्कों को पास करता है, तो ओवरहेड महत्वपूर्ण रूप से बढ़ जाता है। पाइथन 3.5 में माइक्रोबेंचमार्क 'int (" 0 ", 2) 'बनाम' int (" 0 ", base = 2) 'के लिए मेरी मशीन पर दिखाया गया है कि बाद में चलाने के लिए ~ 2.5x लगते हैं; अधिक समय वास्तविक काम की तुलना में तर्क पार्सिंग खर्च किया जाता है। इससे भी बदतर एक ही तर्क लेने वाले कार्यों में एक तेज पथ है जो तर्क रैपिंग से बचाता है, लेकिन कीवर्ड पर जाने का अर्थ है कि तर्कों को 'tuple' और/या 'dict' में लपेटा जाना चाहिए। – ShadowRanger

3

minus(**dict(b=2, a=1))minus(b=2, a=1) तक फैलता है। यह काम करता है क्योंकि आपकी परिभाषा में तर्क नाम a और b हैं।

operator.sub(**dict(b=2, a=1))operator.sub(b=2, a=1) तक फैला हुआ है। यह काम नहीं करता है क्योंकि उप कीवर्ड तर्क स्वीकार नहीं करता है।

+2

मुझे पूरा यकीन है कि वह पूछ रहा है कि यह कीवर्ड तर्क क्यों स्वीकार नहीं करता है और आप इसका उत्तर नहीं दिया है। – jamylak

+0

क्या आप कह रहे हैं कि operator.sub के पास 'minus' नामक इसके तर्क नहीं हैं? – canadadry

+0

@ बोनामी: बिल्कुल। 'operator.sub' के तर्क नामहीन हैं – Eric

4

operator एक सी मॉड्यूल है, जो defines functions differently है। जब तक मॉड्यूल प्रारंभ में फ़ंक्शन घोषणा में METH_KEYWORDS शामिल नहीं है, तो फ़ंक्शन किसी भी परिस्थिति में कीवर्ड तर्क स्वीकार नहीं करेगा और आपको प्रश्न में दी गई त्रुटि मिल जाएगी।

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