2010-02-23 18 views
20

मैं इसे बहुत उपयोगी रनटाइम के दौरान नए चर बना सकते हैं और बाद में प्रसंस्करण के लिए परिणामों का एक शब्दकोश बनाने के लिए, यानी एक फ़ाइल में लिखने के लिए सक्षम होने के लिए लगता है एक स्ट्रिंग आवंटित करने के लिए:पायथन: का प्रयोग वार्स() एक चर

myDict = {} 
for i in range (1,10): 
    temp = "variable"+str(i) 
    vars()[temp] = myFunctionThatReturnsData() # variable1= data1, variable2 = data2,etc. 
    myDict[temp] = vars(temp) 

जो शब्दकोश प्रविष्टि बनाता है [परिणाम 1: डेटा 1] जिसे मैं अपने डिक्ट [परिणाम 1] के साथ कॉल कर सकता हूं। मैं वास्तव में समझने के बिना वर्स() का उपयोग कर रहा हूं कि मैं क्या कर रहा हूं। (?) मैं इसे vars() स्थानीय चर के साथ एक शब्दकोश रिटर्न लेते हैं, और

वार्स() [x] y =

[x: y] की एक नई प्रविष्टि शब्दकोश बनाता है?

मेरे पास एक स्क्रिप्ट है जहां मैं {इनपुट 1: डेटा 1, इनपुट 2: डेटा 2} के साथ तैयार एक शब्दकोश में पास करता हूं, और मैं इस विधि का उपयोग सभी मानों के माध्यम से फिर से करने, सभी परिणामों को स्टोर करने और इसे फ़ाइल में आउटपुट करने के लिए करता हूं। कोड का यह बिट एक वर्ग के भीतर एक समारोह के अंदर है, और काम कर रहा है।

भ्रम की मेरे स्रोत है कि मैं कैसे स्थानीय लोगों पर विभिन्न पदों() के साथ गड़बड़ नहीं किया जाना चाहिए पढ़ा है है, और कैसे वार्स() बराबर (?) स्थानीय लोगों(), या वैश्विक() करने के लिए है ..

तो मेरे सवाल है (कम से कम) दो गुना:

1. क्या वास्तव में वार्स(), करता है या विशेष रूप से, वार्स() [x] = y करते हैं,

गुंजाइश 2.What इस शब्दकोश का है (मुझे क्या ध्यान रखना चाहिए क्योंकि मैं बड़े प्रोग्राम लिखता हूं

3. यह अच्छा प्रोग्रामिंग है अभ्यास।

अग्रिम धन्यवाद!

उत्तर

32

pythonic तरीका चर

का एक अनुक्रम बनाने आप चर का एक अनुक्रम चाहते हैं, एक दृश्य बनाने के लिए।

variable0 
variable1 
variable2 
variable3 

आप एक list बनाने पर गौर करना चाहिए: इसके बजाय की तरह स्वतंत्र चर बनाने का प्रयास करने का। यह वही है S.Lott सुझाव दे रहा है (S.Lott आमतौर पर अच्छी सलाह है) के समान है, लेकिन नक्शे अधिक बड़े करीने से अपने for पाश पर:।

sequence = [] 
for _ in xrange(10): 
    sequence.append(function_that_returns_data()) 

(सूचना है कि हम पाश चर (_ त्यागने) हमें ' फिर सिर्फ 10 गुजरता प्राप्त करने के लिए

फिर अपने डेटा के रूप में उपलब्ध हो जाएगा कोशिश कर):।

sequence[0] 
sequence[1] 
sequence[2] 
sequence[3] 
[...] 
sequence[9] 

एक अतिरिक्त बोनस के रूप में, आप कर सकते हैं:

for datum in sequence: 
    process_data(datum) 

सबसे पहले, आप अपने अनुक्रम 0 पर शुरू होने पर जुड़ सकते हैं। आप अपने वास्तविक डेटा को 1 से शुरू करने के लिए विभिन्न contortions के माध्यम से जा सकते हैं, लेकिन यह इसके लायक से अधिक दर्द है। मैं सिर्फ शून्य-आधारित सूचियों के लिए उपयोग करने की अनुशंसा करता हूं। सबकुछ उनके चारों ओर बनाया गया है, और वे प्राकृतिक रूप से बहुत जल्दी महसूस करना शुरू कर देते हैं।

वार्स() और स्थानीय लोगों()

अब, अपने प्रश्न के दूसरे भाग का जवाब देने की। vars() (या locals()) पायथन द्वारा बनाए गए चर के लिए निम्न स्तर तक पहुंच प्रदान करता है। इस प्रकार निम्नलिखित दो पंक्तियां बराबर हैं।

locals()['x'] = 4 
x = 4 

vars()['x'] के दायरे बिल्कुल x के दायरे के समान है। locals() (या vars()) के साथ एक समस्या यह है कि यह आपको नामस्थान में सामान डालने देगा जिससे आप सामान्य माध्यम से नामस्थान से बाहर नहीं निकल सकते हैं। तो आप इस तरह कुछ कर सकते हैं: locals()[4] = 'An integer', लेकिन आप फिर से स्थानीय लोगों का उपयोग किये बिना इसे वापस नहीं निकाल सकते हैं, क्योंकि स्थानीय नामस्थान (जैसा कि सभी पायथन नामस्थानों के साथ) केवल तारों को पकड़ने के लिए है।

>>> x = 5 
>>> dir() 
['__builtins__', '__doc__', '__name__', 'x'] 
>>> locals()[4] = 'An integer' 
>>> dir() 
[4, '__builtins__', '__doc__', '__name__', 'x'] 
>>> x 
5 
>>> 4 
4 
>>> locals()[4] 
'An integer' 

ध्यान दें कि 4 स्थानीय लोगों() [4] के समान चीज़ नहीं लौटाते हैं। यह कुछ अप्रत्याशित, समस्याओं को डीबग करना मुश्किल हो सकता है। locals() का उपयोग करने से बचने का यह एक कारण है।दूसरा यह है कि आम तौर पर चीजों को करने के लिए यह बहुत जटिलता है कि पायथन सरल, कम त्रुटि प्रवण तरीकों को प्रदान करता है (जैसे चर के अनुक्रम बनाना)।

+2

मुझे लगता है कि 'vars() [' x '] = 4' और 'x = 4' वास्तव में केवल कुछ समय के बराबर हैं। यदि आप इसे किसी फ़ंक्शन में करते हैं, और 'x' कहीं और सेट नहीं करते हैं, और फ़ंक्शन को कंपाइलर द्वारा अनुकूलित किया जाता है, तो फ़ंक्शन में बाद में' x' का सामान्य लुकअप (यानी, 'y = x + 2') जीता काम नहीं करता मुझे लगता है कि कंपाइलर कैश जो चर देख सकते हैं (संभावित रूप से संकलन समय पर परिभाषित किए गए थे), और इस तरह के शेंगेनिगन को ध्यान में रखते हैं। यदि आप अपने फ़ंक्शन में निष्पादन कथन जोड़ते हैं, तो संकलक फ़ंक्शन को अनुकूलित करने का प्रयास नहीं करेगा। –

+1

विचारशील उत्तर के लिए धन्यवाद, क्रम में डेटाम के लिए: फ़ंक्शन (डेटाम) बहुत उपयोगी लगता है। यहां बहुत कुछ है जो मैंने आज सीखा, धन्यवाद! – PPTim

+0

उस निर्माण पर अधिक जानकारी प्राप्त करने के लिए, "पायथन इटरेटर्स" देखें – jcdyer

2

मैं नंबर 3 का उत्तर दे सकता हूं: यह अच्छा प्रोग्रामिंग अभ्यास नहीं है। मैं बिल्कुल नहीं देखता कि आप क्या हासिल करने की कोशिश कर रहे हैं, लेकिन मुझे यकीन है कि locals() (जो vars() के समान है, help(vars) इंटरैक्टिव पायथन शेल में) के बिना ऐसा करने का एक और शानदार तरीका है।

5

वार्स के लिए मदद से,

वार्स (...) वार्स ([वस्तु]) -> शब्दकोश

Without arguments, equivalent to locals(). 
With an argument, equivalent to object.__dict__. 

आप इसे वार्स के बिना उपयोग कर रहे हैं, तो चलो स्थानीय लोगों के लिए सहायता देखें()

स्थानीय (...) स्थानीय() -> शब्दकोश

Update and return a dictionary containing the current scope's local 

चर।

तो यह आपको पहले दो प्रश्नों का उत्तर देता है। vars() स्थानीय चरों में एक शब्दकोश देता है जो एक स्ट्रिंग के रूप में चर के नाम से अनुक्रमित होता है। दायरा स्थानीय है।

मुझे तीसरे प्रश्न के बारे में निश्चित नहीं है, लेकिन ऐसा लगता है कि एक हैक जो एक अच्छा संकेत नहीं है।मुझे लगता है कि अगर आप केवल सही दायरे में इसका उपयोग करने के बारे में सावधान हैं तो आप इसके साथ प्राप्त कर सकते हैं।

+0

मैं तो मेरे भ्रम की स्थिति मैं मदद के लिए पूछना भूल गया() में पकड़ा गया। धन्यवाद, – PPTim

6

इसके बजाए ऐसा करें। यह आसान है।

myDict = {} 
for i in range (1,10): 
    temp = "variable"+str(i) 
    myDict[temp] = myFunctionThatReturnsData() # variable1= data1, variable2 = data2,etc. 

आपको बस इतना करना है।

परिणाम हो myDict['variable1'] के माध्यम से myDict['variable9']

आप शायद ही कभी vars() या locals() की आवश्यकता होगी। बस उनका उपयोग बंद करो और सामान्य चर और सामान्य शब्दकोश का उपयोग करें। उन चीज़ों से बचने की कोशिश करें जिन्हें आप समझ में नहीं आते हैं और सरल, स्पष्ट सामग्री से चिपके रहते हैं।

+0

अब मुझे लगता है कि मैंने वर्र्स() का उपयोग क्यों किया, शायद यह इसलिए था क्योंकि जब मैंने लाइन लाइन कोड का परीक्षण किया तो आईडीएलई के ठीक से चर को कॉल करने में सक्षम होना अच्छा लगा। जवाब के लिए धन्यवाद! – PPTim

1

इस तरह से वर्र्स/स्थानीय या ग्लोबल्स का उपयोग करना (ए) खराब अभ्यास और (बी) सभी मामलों में काम नहीं करता है। अधिक जानकारी के लिए Dynamically set local variable देखें। निचली पंक्ति: बस डिक्ट्स का उपयोग करें - यही वह है जो वे हैं।

4

जेसीडीयर अवधारणाओं को बहुत अच्छी तरह से बताता है और जस्टिन छील स्पष्ट रूप से बताता है कि vars() और locals() क्या करते हैं। लेकिन एक छोटा सा उदाहरण हमेशा समझ को गति देता है।

class Bull(object): 

    def __init__(self): 
     self.x = 1 
     self.y = "this" 

    def __repr__(self): 
     return "Bull()" 

    def test1(self): 
     z = 5 
     return vars() 

    def test2(self): 
     y = "that" 
     return vars(self) 

    def test3(self): 
     return locals() 

    def test4(self): 
     y = 1 
     return locals() 

if __name__ == "__main__": 
    b = Bull() 
    print b.test1() 
    print b.test2() 
    print b.test3() 
    print b.test4() 
    print vars(b).get("y") 

में कौन सा परिणाम:

{'self': Bull(), 'z': 5} 
{'y': 'this', 'x': 1} 
{'self': Bull()} 
{'y': 1, 'self': Bull()} 
this 
संबंधित मुद्दे