2011-11-18 10 views
6

निम्नलिखित कोडमैंने सोचा कि पायथन संदर्भ से सब कुछ पारित कर दिया है?

#module functions.py 
def foo(input, new_val): 
    input = new_val 

#module main.py 
input = 5 
functions.foo(input, 10) 

print input 

मैंने सोचा था कि इनपुट अब 10 हो जाएगा ले लो क्यों यह स्थिति नहीं है?

+0

आप फ़ंक्शन foo की परिभाषा में स्थानीय चर "इनपुट" को कॉल करके स्वयं को भ्रमित कर सकते हैं। इसके अलावा, उत्तर में क्या स्वेन ने कहा। – phkahler

+6

जहां भी आपने पढ़ा है कि पाइथन संदर्भ से सबकुछ पास करता है, वे गलत थे। –

उत्तर

13

सब कुछ मूल्य से गुजरता है, लेकिन यह मान मूल वस्तु का संदर्भ है। यदि आप ऑब्जेक्ट को संशोधित करते हैं, तो कॉलर के लिए परिवर्तन दिखाई दे रहे हैं, लेकिन आप नामों को फिर से असाइन नहीं कर सकते हैं। इसके अलावा, कई वस्तुएं अपरिवर्तनीय हैं (इनट्स, फ्लोट्स, स्ट्रिंग्स, टुपल्स)।

+8

"[Idiomatic Python] (http://python.net/~goodger/projects/pycon/2007/idiomatic/handout.html#other- भाषाएं- have-variables)" इस घटना को अच्छी तरह से दिखाता है। –

+1

पायथन कॉल-बाय-वैल्यू या कॉल-बाय-रेफरेंस नहीं है, विवरण के लिए मेरा उत्तर देखें। –

+1

@skyhisi: आपका उत्तर अनिवार्य रूप से मेरे जैसा ही है, गैर-मानक शब्द "ऑब्जेक्ट द्वारा कॉल करें" का उपयोग करने के अलावा, जिसे मैं जानबूझकर टालता हूं क्योंकि यह किसी भी तरह की व्याख्या नहीं करता है। –

8

foo के अंदर, आप एक अलग वस्तु (10) करने के लिए स्थानीय नाम input बाध्यकारी रहे हैं। कॉलिंग संदर्भ में, नाम input अभी भी 5 ऑब्जेक्ट को संदर्भित करता है।

5

पायथन में असाइनमेंट किसी ऑब्जेक्ट को जगह में संशोधित नहीं करता है। यह एक नाम rebinds ताकि input = new_val के बाद, स्थानीय चर input एक नया मूल्य प्राप्त हो जाता है।

def foo(input, new_val): 
    input[0] = new_val 

foo([input]) 

अजगर पास-संदर्भ द्वारा करते नहीं करता है:

आप "बाहर" input को संशोधित करना चाहते हैं, तो आप इस तरह के एक एक तत्व सूची के रूप में एक अस्थायी ऑब्जेक्ट के अंदर लपेट करना होगा वास्तव में जिस तरह से सी ++ संदर्भ गुजरता है काम करता है। कम से कम इस मामले में, यह अधिक है के रूप में अगर हर तर्क C/C++ में एक सूचक है:

// effectively a no-op! 
void foo(object *input, object *new_val) 
{ 
    input = new_val; 
} 
+0

सभी के उत्तरों के लिए धन्यवाद ... आपके द्वारा सुझाई गई यह विधि लगभग हैक की तरह दिखती है, क्या यह मानक प्रक्रिया है? क्या अपरिवर्तनीय प्रकारों को संशोधित करने के लिए कोई और तरीका है जो अधिक पाइथनिक है? (मुझे लगता है कि 'अपरिवर्तनीय प्रकारों को संशोधित करें' मेरे अपने प्रश्न का उत्तर दें लेकिन मैं वैसे भी पूछूंगा ...) – Ferguzz

+0

@ फ़र्गज़ आप परिभाषा के द्वारा अपरिवर्तनीय वस्तुओं को संशोधित नहीं कर सकते हैं। लेकिन क्या वास्तव में आप पूछना चाहते थे? अब तक, अपरिवर्तनीय वस्तुओं का भी उल्लेख नहीं किया गया है। तथ्य यह है कि 'var = ...' किसी ऑब्जेक्ट को संशोधित नहीं करता है या किसी अन्य चर के पास अपरिवर्तनीयता के साथ कुछ भी नहीं है। आप बस एक वैरिएबल असाइनमेंट को अन्य वैरिएबल नहीं बदल सकते हैं जैसे कि आप एक सूची में बदलाव नहीं कर सकते हैं, दूसरी सूची को प्रभावित करते हैं। – delnan

+0

मैं इस जवाब में रेखा का जिक्र कर रहा था 'इसे एक सूची के रूप में एक म्यूटेबल ऑब्जेक्ट के अंदर लपेटें'। मैं पूछने की कोशिश कर रहा था, क्या ऐसा करने के बिना, मेरी मूल पोस्ट में वैरिएबल को संशोधित करने का कोई तरीका है? – Ferguzz

3

अजगर न कॉल-दर-मूल्य है, या कॉल-दर-संदर्भ, यह Call By Object है।

"तर्क समान कि तर्क वस्तुओं हैं और केवल बदला जा सकता है अगर वे परिवर्तनशील हैं को छोड़कर कॉल-दर-मूल्य, लिए, कॉल-दर-बंटवारे से पारित कर रहे हैं।"

+1

अच्छा सारांश, लेकिन फिर भी मुझे विश्वास है कि कॉल-बाय-ऑब्जेक्ट कॉल-बाय-वैल्यू से अलग नहीं है, सभी "मान" ऑब्जेक्ट्स को हैंडल (~ = पॉइंटर्स) के साथ हैं। – Kos

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