पायथन के साथ लंबे समय से छेड़छाड़ करने वाले किसी भी व्यक्ति को निम्नलिखित मुद्दे से काट दिया गया है (या टुकड़े टुकड़े कर दिया गया है):
def foo(a=[]):
a.append(5)
return a
पायथन नौसिखियों को इस फ़ंक्शन से हमेशा केवल एक तत्व के साथ एक सूची वापस करने की उम्मीद होगी [5]
:। परिणाम इसके बजाय बहुत अलग है, और बहुत आश्चर्यजनक है (एक नौसिखिए के लिए):
>>> foo()
[5]
>>> foo()
[5, 5]
>>> foo()
[5, 5, 5]
>>> foo()
[5, 5, 5, 5]
>>> foo()
मेरे एक प्रबंधक ने एक बार इस विशेषता के साथ अपनी पहली मुठभेड़ की थी, और इसे भाषा का "नाटकीय डिजाइन दोष" कहा। मैंने जवाब दिया कि व्यवहार में एक अंतर्निहित स्पष्टीकरण था, और यह वास्तव में बहुत ही हैरान और अप्रत्याशित है यदि आप आंतरिक को नहीं समझते हैं। हालाँकि, मैं निम्नलिखित प्रश्न का उत्तर (स्वयं को) देने में सक्षम नहीं था: फ़ंक्शन परिभाषा में डिफ़ॉल्ट तर्क को बांधने का क्या कारण है, और फ़ंक्शन निष्पादन पर नहीं? मुझे संदेह है कि अनुभवी व्यवहार का एक व्यावहारिक उपयोग है (जो वास्तव में सी में स्थैतिक चर का उपयोग करते हैं, बग प्रजनन के बिना?)
संपादित करें :
बेज़ेक ने एक दिलचस्प उदाहरण बनाया। आपकी अधिकांश टिप्पणियों और साथ में विशेष रूप से उतल की, मैंने आगे विस्तार से बताया:
>>> def a():
... print("a executed")
... return []
...
>>>
>>> def b(x=a()):
... x.append(5)
... print(x)
...
a executed
>>> b()
[5]
>>> b()
[5, 5]
मेरे लिए, ऐसा लगता है कि डिजाइन का निर्णय मानकों के दायरे के सापेक्ष था: फ़ंक्शन के अंदर या इसके साथ "एक साथ"?
फ़ंक्शन के अंदर बाइंडिंग करने का मतलब यह होगा कि x
फ़ंक्शन को कॉल किए जाने पर निर्दिष्ट डिफ़ॉल्ट पर प्रभावी रूप से बाध्य है, परिभाषित नहीं है, ऐसा कुछ जो एक गहरी खामी पेश करेगा: def
लाइन इस अर्थ में होगी कि बाध्यकारी का हिस्सा फ़ंक्शन ऑब्जेक्ट) परिभाषा, और फ़ंक्शन इनवोकेशन समय पर डिफ़ॉल्ट पैरामीटर (असाइनमेंट) का हिस्सा होगा।
वास्तविक व्यवहार अधिक सुसंगत है: उस रेखा के निष्पादित होने पर उस पंक्ति की हर चीज का मूल्यांकन किया जाता है, जिसका अर्थ फ़ंक्शन परिभाषा है।
[5]
"। मैं एक अजगर नौसिखिया हूँ, और मैं यह उम्मीद नहीं foo([1])
करूँगा , क्योंकि जाहिर है [1, 5]
, वापस आ जाएगा , नहीं [5]
। आपके कहने का मतलब यह है कि एक नौसिखिए से यह अपेक्षा की जाती है कि बिना किसी पैरामीटर के बुलाए गए फ़ंक्शन हमेशा वापस आएंगे [5]
।