तर्क असाइनमेंट द्वारा पारित किए जाते हैं । इसके पीछे तर्क दोहरा है:
- पैरामीटर में पारित कर दिया वास्तव में एक है संदर्भ किसी ऑब्जेक्ट को (लेकिन संदर्भ मूल्य से पारित हो जाता है)
- कुछ डेटा प्रकार परस्पर हैं, लेकिन अन्य नहीं हैं
इसलिए:
यदि आप किसी परिवर्तनशील वस्तु को किसी विधि में पास करते हैं, तो विधि को उसी वस्तु का संदर्भ मिलता है और आप इसे अपने दिल की खुशी के लिए बदल सकते हैं, लेकिन यदि आप विधि में संदर्भ को वापस लेते हैं, तो बाहरी गुंजाइश इसके बारे में कुछ नहीं जानती है, और उसके बाद आप कर रहे हैं, बाहरी संदर्भ अभी भी मूल वस्तु पर इंगित करेगा।
यदि आप किसी विधि से अपरिवर्तनीय वस्तु को पास करते हैं , तो आप अभी भी बाहरी संदर्भ को अस्वीकार नहीं कर सकते हैं, और आप ऑब्जेक्ट को म्यूट भी नहीं कर सकते।
इसे और अधिक स्पष्ट करने के लिए, आइए कुछ उदाहरण देखें।
सूची - एक उत्परिवर्तित प्रकार
आइए उस सूची को संशोधित करने का प्रयास करें जो एक विधि से पारित की गई थी:
def try_to_change_list_contents(the_list):
print('got', the_list)
the_list.append('four')
print('changed to', the_list)
outer_list = ['one', 'two', 'three']
print('before, outer_list =', outer_list)
try_to_change_list_contents(outer_list)
print('after, outer_list =', outer_list)
आउटपुट:
before, outer_list = ['one', 'two', 'three']
got ['one', 'two', 'three']
changed to ['one', 'two', 'three', 'four']
after, outer_list = ['one', 'two', 'three', 'four']
चूंकि इसमें दिया गया पैरामीटर इसका संदर्भ है outer_list
, इसकी प्रति नहीं, हम इसे बदलने के लिए उत्परिवर्तन सूची विधियों का उपयोग कर सकते हैं और बाहरी दायरे में परिलक्षित परिवर्तन हो सकते हैं।
अब देखते हैं कि जब हम एक पैरामीटर के रूप में पारित किए गए संदर्भ को बदलने की कोशिश करते हैं तो क्या होता है:
def try_to_change_list_reference(the_list):
print('got', the_list)
the_list = ['and', 'we', 'can', 'not', 'lie']
print('set to', the_list)
outer_list = ['we', 'like', 'proper', 'English']
print('before, outer_list =', outer_list)
try_to_change_list_reference(outer_list)
print('after, outer_list =', outer_list)
आउटपुट:
before, outer_list = ['we', 'like', 'proper', 'English']
got ['we', 'like', 'proper', 'English']
set to ['and', 'we', 'can', 'not', 'lie']
after, outer_list = ['we', 'like', 'proper', 'English']
चूंकि the_list
पैरामीटर मान द्वारा पारित किया गया था, इसलिए इसे एक नई सूची सौंपने का कोई प्रभाव नहीं था कि विधि के बाहर का कोड देख सकता था। the_list
की एक प्रति था outer_list
संदर्भ, और हम था the_list
एक नई सूची इंगित, लेकिन वहाँ जहां बदलने के लिए कोई रास्ता नहीं था outer_list
उठाई।
स्ट्रिंग - एक अपरिवर्तनीय प्रकार
यह अपरिवर्तनीय है, इसलिए स्ट्रिंग की सामग्री को बदलने के लिए हम कुछ नहीं कर सकते
अब, संदर्भ बदलने की कोशिश करते हैं
def try_to_change_string_reference(the_string):
print('got', the_string)
the_string = 'In a kingdom by the sea'
print('set to', the_string)
outer_string = 'It was many and many a year ago'
print('before, outer_string =', outer_string)
try_to_change_string_reference(outer_string)
print('after, outer_string =', outer_string)
आउटपुट:
before, outer_string = It was many and many a year ago
got It was many and many a year ago
set to In a kingdom by the sea
after, outer_string = It was many and many a year ago
फिर से, चूंकि the_string
पैरामीटर मान द्वारा पारित किया गया था , इसलिए इसे एक नया स्ट्रिंग असाइन करने का कोई प्रभाव नहीं था कि विधि के बाहर का कोड देख सकता था। the_string
की एक प्रति था outer_string
संदर्भ, और हम था the_string
एक नया स्ट्रिंग के लिए बिंदु, लेकिन वहाँ जहां बदलने के लिए कोई रास्ता नहीं था outer_string
उठाई।
मुझे उम्मीद है कि इससे चीजें थोड़ी साफ होंगी।
संपादित करें: यह नोट किया गया है कि यह इस सवाल का जवाब नहीं देता है कि @ डेविड ने मूल रूप से पूछा, "क्या कुछ ऐसा है जिसे मैं वास्तविक संदर्भ द्वारा चर को पारित करने के लिए कर सकता हूं?" चलो उस पर काम करते हैं।
हम इसके आसपास कैसे पहुंचते हैं?
जैसा कि @ एंड्रिया के जवाब से पता चलता है, आप नया मान वापस कर सकते हैं। यह चीजों को पास करने के तरीके को नहीं बदलता है, लेकिन क्या आपको वह जानकारी प्राप्त करने देता है जो आप वापस चाहते हैं:
def return_a_whole_new_string(the_string):
new_string = something_to_do_with_the_old_string(the_string)
return new_string
# then you could call it like
my_string = return_a_whole_new_string(my_string)
यदि आप वास्तव में रिटर्न वैल्यू का उपयोग करने से बचना चाहते हैं, तो आप अपना मान रखने के लिए एक क्लास बना सकते हैं और इसे फंक्शन में पास कर सकते हैं या किसी लिस्ट की तरह मौजूदा क्लास का उपयोग कर सकते हैं:
def use_a_wrapper_to_simulate_pass_by_reference(stuff_to_change):
new_string = something_to_do_with_the_old_string(stuff_to_change[0])
stuff_to_change[0] = new_string
# then you could call it like
wrapper = [my_string]
use_a_wrapper_to_simulate_pass_by_reference(wrapper)
do_something_with(wrapper[0])
हालांकि यह थोड़ा बोझिल लगता है।