2012-04-12 13 views
5

में डिफ़ॉल्ट पैरामीटर कहां है, मुझे लगता है कि कई लोगों ने पाइथन के फ़ंक्शन को देखा है जो डिफ़ॉल्ट पैरामीटर प्राप्त करता है। उदाहरण के लिए:पायथन फ़ंक्शन

def foo(a=[]): 
    a.append(3) 
    return a 

अगर हम foo (का प्रयोग करके) इस समारोह फोन, उत्पादन पूर्णांक कॉल के बाद हर बार जोड़ देंगे, '3'।

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

मेरा प्रश्न है, यह मूल्यांकन पैरामीटर कहां है? क्या यह फ़ंक्शन ऑब्जेक्ट में है या फ़ंक्शन को कॉल करते समय यह विधि ऑब्जेक्ट में है? चूंकि पाइथन में सब कुछ एक वस्तु है, इसलिए 'ए' -> मूल्यांकन पैरामीटर का नाम बाध्यकारी नाम रखने के लिए कुछ जगह होनी चाहिए। क्या मैं इस समस्या को खत्म कर रहा हूं?

उत्तर

10

जैसा कि पहले से ही कहा गया है, डिफ़ॉल्ट मान फ़ंक्शन ऑब्जेक्ट में संग्रहीत हैं।

उदाहरण के लिए, CPython में आप यह कर सकते हैं:

>>> def f(a=[]): 
...  pass 
... 
>>> f.func_defaults 
([],) 
>>> f.func_code.co_varnames 
('a',) 
>>> 

हालांकि, co_varnames आर्ग के नाम से भी अधिक हो सकती है तो यह आगे की प्रक्रिया की जरूरत है और इन विशेषताओं भी अन्य अजगर कार्यान्वयन में नहीं हो सकता है। इसलिए आप inspect मॉड्यूल के बजाय जो आप के लिए सभी कार्यान्वयन विवरण का ख्याल रखता है का उपयोग करना चाहिए:

>>> import inspect 
>>> spec = inspect.getargspec(f) 
>>> spec 
ArgSpec(args=['a'], varargs=None, keywords=None, defaults=([],)) 
>>> 

ArgSpec है एक नामित टपल ताकि आप विशेषताओं के रूप में सभी मूल्यों को एक्सेस कर सकते हैं:

>>> spec.args 
['a'] 
>>> spec.defaults 
([],) 
>>> 

documentation के रूप में कहते हैं, defaults ट्यूपल हमेशा args से अंतिम तर्कों के अनुरूप है। यह आपको अपना मानचित्रण देता है।

>>> dict(zip(spec.args[-len(spec.defaults):], spec.defaults)) 
{'a': []} 
>>> 
4

यह समारोह वस्तु से अनुलग्न है, को देखने के foo.func_defaults:

>>> foo() 
>>> foo.func_defaults 
([3],) 
>>> foo() 
>>> foo.func_defaults 
([3, 3],) 

आप [] पर a की मैपिंग प्राप्त करना चाहते हैं, तो मामले में, आप उपयोग कर सकते हैं foo.func_code:

defaults = foo.func_defaults 
# the args are locals in the beginning: 
args = foo.func_code.co_varnames[:foo.func_code.co_argcount] 
def_args = args[-len(defaults):] # the args with defaults are in the end 
print dict(zip(def_args, defaults)) # {'a': []} 

(लेकिन, जाहिर है, याक का संस्करण बेहतर है।)

+2

हां, लेकिन ओपी के रूप में '[]' के लिए 'a' का मैपिंग कहां है? – MattH

+0

@MattH उत्तर को अपडेट किया गया, धन्यवाद। – bereal

4

यह func_defaults में फ़ंक्शन ऑब्जेक्ट में है :

def f(a=[]): a.append(3) 

print f.func_defaults # ([],) 

f() 

print f.func_defaults # ([3],) 
+2

हां, लेकिन ओपी के रूप में [] के मैपिंग कहां है? – MattH

2

यह समारोह वस्तु की func_defaults विशेषता में संग्रहित है।

>>> foo.func_defaults 
([],) 
>>> foo() 
([3],) 
1

मैं एक दिलचस्प स्थिति पाया है: अजगर 2.5 में

एक dict आप ऐसा कर सकता है बनाने के लिए।

>>> id(foo()) 
4336826757314657360 
>>> id(foo()) 
4336826757314657008 
>>> id(foo()) 
4336826757314683160 

2.7.2 में संस्करण:

>>> foo() 
[1] 
>>> foo() 
[1, 1] 
>>> foo() 
[1, 1, 1] 

इस में क्योंकि समारोह कहा जाता है की वस्तुओं अलग हैं 2 संस्करण, समारोह 'foo()'

>>> foo() 
[1] 
>>> foo() 
[1] 
>>> foo() 
[1] 

कोशिश मामला, ऑब्जेक्ट फ़ंक्शन को कॉल करते समय प्रत्येक बार होता है:

>>> id(foo()) 
29250192 
>>> id(foo()) 
29250192 
>>> id(foo()) 
29250192 

क्या यह विभिन्न संस्करणों की एक समस्या है?

+0

नहीं होना चाहिए। सुनिश्चित करें कि आप दोनों संस्करणों पर * बिल्कुल * एक ही फ़ंक्शन का उपयोग कर रहे हैं। – yak

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