संक्षिप्त उत्तर है, पायथन हमेशा पास-पास-मूल्य करता है, लेकिन प्रत्येक पायथन चर वास्तव में किसी वस्तु का सूचक होता है, इसलिए कभी-कभी यह पास-बाय-रेफरेंस जैसा दिखता है।
पायथन में प्रत्येक वस्तु या तो उत्परिवर्तनीय या गैर-उत्परिवर्तनीय होती है। उदाहरण के लिए, सूचियाँ, डक्ट्स, मॉड्यूल और पंडस डेटा फ़्रेम परस्पर भिन्न हैं, और इन्ट्स, स्ट्रिंग्स और ट्यूपल गैर-परस्पर हैं। म्यूटेबल ऑब्जेक्ट्स को आंतरिक रूप से बदला जा सकता है (उदाहरण के लिए, किसी सूची में एक तत्व जोड़ें), लेकिन गैर-परिवर्तनशील ऑब्जेक्ट नहीं कर सकते।
जैसा कि मैंने शुरुआत में कहा था, आप हर पायथन वैरिएबल को एक ऑब्जेक्ट के लिए एक पॉइंटर के रूप में सोच सकते हैं। जब आप किसी फ़ंक्शन में एक चर पास करते हैं, तो फ़ंक्शन के भीतर चर (पॉइंटर) हमेशा उस चर (पॉइंटर) की एक प्रति होती है जो अंदर पारित किया गया था। इसलिए यदि आप आंतरिक चर के लिए कुछ नया असाइन करते हैं, तो आप जो कर रहे हैं वह सब बदल रहा है। किसी भिन्न वस्तु की ओर संकेत करने वाला स्थानीय चर। यह उस मूल वस्तु को परिवर्तित (म्यूट) नहीं करता है जिसे चर ने इंगित किया है, और न ही यह बाहरी चर को नई वस्तु के लिए बनाता है। इस बिंदु पर, बाहरी चर अभी भी मूल वस्तु को इंगित करता है, लेकिन आंतरिक चर एक नई वस्तु को इंगित करता है।
यदि आप मूल ऑब्जेक्ट (केवल संभव डेटा प्रकारों के साथ) को बदलना चाहते हैं, तो आपको ऐसा कुछ करना होगा जो स्थानीय चर के लिए पूरी तरह से नया मान निर्दिष्ट किए बिना ऑब्जेक्ट को बदल देता है । यही कारण है कि letgo()
और letgo3()
बाहरी आइटम अनछुए छोड़ देते हैं, लेकिन letgo2()
यह बदलती जाती है।
जैसा कि @ursan ने बताया, यदि letgo()
इसके बजाय ऐसा कुछ इस्तेमाल किया जाता है, तो यह मूल वस्तु को बदल देगा ( df
इंगित करेगा), जो वैश्विक a
चर के माध्यम से देखे गए मूल्य को बदल देगा :
def letgo(df):
df.drop('b', axis=1, inplace=True)
a = pd.DataFrame({'a':[1,2], 'b':[3,4]})
letgo(a)
कुछ मामलों में, आप मूल चर को पूरी तरह से खोखला कर सकते हैं और इसे नए डेटा के साथ फिर से भरना कर सकते हैं, वास्तव में एक प्रत्यक्ष असाइनमेंट किए बिना, उदाहरण के लिए यह मूल वस्तु को बदल देगा जो v
इंगित करता है, जो v
बाद में उपयोग किए जाने पर देखे गए डेटा को बदल देगा :
def letgo3(x):
x[:] = np.array([[3,3],[3,3]])
v = np.empty((2, 2))
letgo3(v)
ध्यान दें कि मैं सीधे कुछ नहीं बता रहा हूँ x
; मैं संपूर्ण आंतरिक श्रेणी में कुछ निर्दिष्ट कर रहा हूं x
।
यदि आपको पूरी तरह से एक नई वस्तु बनानी चाहिए और इसे बाहरी रूप से दिखाई देना चाहिए (जो कि कभी-कभी पांडा के साथ होता है), तो आपके पास दो विकल्प हैं। 'स्वच्छ' विकल्प नई वस्तु को वापस करने के लिए होगा, जैसे,
def letgo(df):
df = df.drop('b',axis=1)
return df
a = pd.DataFrame({'a':[1,2], 'b':[3,4]})
a = letgo(a)
एक अन्य विकल्प आपके फ़ंक्शन के बाहर तक पहुंचना और सीधे एक वैश्विक चर को बदलना होगा। यह परिवर्तन a
एक नई वस्तु की ओर इशारा करता है, और a
बाद में संदर्भित किसी भी फ़ंक्शन को वह नई वस्तु दिखाई देगी:
def letgo():
global a
a = a.drop('b',axis=1)
a = pd.DataFrame({'a':[1,2], 'b':[3,4]})
letgo()
प्रत्यक्ष रूप से वैश्विक चर को बदलना आमतौर पर एक बुरा विचार है, क्योंकि जो कोई भी आपके कोड को पढ़ता है, उसे यह पता लगाने में कठिन समय होगा कि कैसे a
बदल गया। (मैं आम तौर पर एक स्क्रिप्ट में कई कार्यों द्वारा उपयोग किए जाने वाले साझा मापदंडों के लिए वैश्विक चर का उपयोग करता हूं, लेकिन मैं उन्हें उन वैश्विक चर को बदलने नहीं देता।)