2011-02-01 12 views
8

Possible Duplicate:
How to programmatically set a global (module) variable?पायथन में प्रोग्राम बनाने चर

मैं एक वर्ग चर बुलाया इतनी के रूप में परिभाषित किया है:

class Variable(): 
    def __init__(self, name): 
     self.name = name 
     self._value = None 
    def value(self): 
     return self._value 
    def __repr__(self): 
     return self.name 

मैं इस तरह चर के 26 राजधानी एकल अक्षर उदाहरणों बनाना चाहते हैं:

A = Variable('A') 
B = Variable('B') 
... 
Z = Variable('Z') 

अब तक मैंने विभिन्न समाधानों का प्रयास किया है, और सबसे अच्छा मैं साथ आया हूं:

from string import uppercase 
for char in uppercase: 
    exec "%s = %s" % (char, Variable(str(char))) in None 

बहरहाल, यह नहीं चलता है और मुझे इस त्रुटि देता है:

Traceback (most recent call last): 
    File "C:\Users\Administrator\Dev\python\truthtable\truthtable.py", line 7, in <module> 
    exec "%s = %s" % (char, Variable(str(char))) in None 
    File "<string>", line 1, in <module> 
NameError: name 'A' is not defined 

क्या मैं गलत कर रहा हूँ?

+8

गतिशील रूप से चर बनाने की कोशिश करने के अलावा? –

+0

एर, प्रश्न का नाम थोड़ा गड़बड़ है, मैं इस तरह के अर्थशास्त्र में भी चिपक गया हूं। – deeb

+1

@ डीबीबी - मुझे नहीं लगता कि इग्नासिओ आपके शीर्षक का जिक्र कर रहा था। – senderle

उत्तर

15
from string import uppercase 
_g = globals() 
for char in uppercase: 
    _g[char] = Variable(char) 

यह है कि क्या एक अच्छा विचार संदिग्ध :) रहता

globals() के लिए यह केवल काम करता है (यानी मॉड्यूल स्तर के कार्य), भाषा परिभाषा के रूप में स्पष्ट रूप से कहा शब्दकोश locals() द्वारा लौटाए गए संशोधित कि नहीं हो सकता वास्तव में किसी भी स्थानीय चर के मूल्य को बदलें।

आप कक्षा या उदाहरण के __dict__ के साथ कुछ भी ऐसा कर सकते हैं।

+0

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

+1

यह सही नहीं है - यह चेतावनी * केवल * स्थानीय लोगों को लागू होती है।) ग्लोबल्स() को भाषा spec द्वारा सही ढंग से काम करने की गारंटी है। – ncoghlan

+0

@ncoghian: यहां मूल है एलेक्स द्वारा टिप्पणी, जो तर्कसंगत रूप से एक बहुत अनुभवी पायथन प्रोग्रामर है: http://stackoverflow.com/questions/1429814/how-to-programmatically-set-a-global-module-variable :) – EOL

0
from string import uppercase 
for c in uppercase: 
    locals()[c] = Variable(c) 
print A 

मुझे यकीन नहीं है कि आप ऐसा क्यों करना चाहते हैं, हालांकि।

+2

यह आधिकारिक रूप से असफल हो सकता है: "इस शब्दकोश की सामग्री को संशोधित नहीं किया जाना चाहिए; परिवर्तन दुभाषिया द्वारा उपयोग किए जाने वाले स्थानीय और निःशुल्क चर के मानों को प्रभावित नहीं कर सकता है।" (दस्तावेज से)। – EOL

4

ठीक है, यह बहुत नहीं है, लेकिन आप globals() शब्दकोश सीधे पहुंच सकते हैं:

for c in 'ABC': 
    globals()[c] = Variable(c) 
+1

"विशेषता असाइनमेंट मॉड्यूल के नामस्थान शब्दकोश को अद्यतन करता है, उदाहरण के लिए, m.x = 1 m .__ dict __ [" x "] = 1. के बराबर है।" (http://docs.python.org/reference/datamodel.html से) – ncoghlan

3

आप यहाँ के रूप में अन्य उत्तर दिखाने के लिए, इस के लिए exec उपयोग करने की आवश्यकता नहीं है, लेकिन अपने मूल के साथ समस्या यह है कोड:

for char in uppercase: 
    exec "%s = %s" % (char, Variable(str(char))) in None 

यह A = A, B = B, आदि exec अगर आप निष्पक्षतावाद का प्रबल अनुयायी रहे इस दिलचस्प हो सकता है, अजगर इसके लिए बहुत ज्यादा परवाह नहीं करेंगे। आप exec उपयोग करने के लिए, पहले नहीं करने की कोशिश कोशिश कर रहे हैं,

for char in uppercase: 
    exec "%s = Variable('%s')" % (char, char) 

भविष्य में:

आप इसे बात करने के लिए कार्यकारी अंदर Variable() सामान करना चाहते हैं। दूसरा, प्रिंट करें जो आप निष्पादित कर रहे हैं - इससे डीबग करने में मदद मिलेगी।

+0

कोई डाउनवोट नहीं है, लेकिन मेरे उत्तर में स्पष्ट रूप से एक क्लीनर तरीका (और संभवतः तेज़ तरीका है, यदि यह मायने रखता है)। – EOL

+0

बेशक, मैं कहता हूं कि मैं अपने उत्तर में ऐसा नहीं करता हूं। यह मूल कोड का एक निश्चित संस्करण है जो वास्तव में 'exec' का उपयोग करता है। – tkerwin

7

अब तक साफ दृष्टिकोण है कि मैंने कभी देखा है सीधे (यानी मुख्य मॉड्यूल), के रूप में another question on StackOverflow में दिए अपने कार्यक्रम के लिए चर (यानी विशेषताओं) जोड़ने के लिए है:

import sys 
from string import ascii_uppercase 

this_module = sys.modules[__name__] 
for char in ascii_uppercase: 
    setattr(this_module, char, Variable(char)) 

print A # Works! 

पुनश्च: अजगर कोर डेवलपर्स ने globals() को संशोधित करने के लिए कड़ी मेहनत की है (टिप्पणियां ncoghlan के उत्तर में देखें)। तो, globals() संशोधित करना एक विकल्प है।मुझे यकीन नहीं है कि बहुत से लोग क्यों महसूस करते हैं कि यह इतना साफ नहीं है, हालांकि (शायद क्योंकि globals() संशोधित किया जा सकता है स्पष्ट रूप से दस्तावेज नहीं है?)।

2

इसे वैश्विक चर में चिपकाने की कोशिश न करें। यह डरावना है। इसके बजाए ऐसा करो।

import string 

variables = {} 
for x in string.ascii_uppercase: 
    variables[x] = Variable(x) 

आप इसे variables['Q'] से एक्सेस करते हैं, उदाहरण के लिए।

आप का उपयोग विशेषता चाहते हैं तो आप कर सकते हैं:

class Variables(object): pass 

और

variables = Variables() 
for x in string.ascii_uppercase: 
    setattr(variables, x) = Variable(x) 

लेकिन उस मामले में मैं नहीं बल्कि उन्हें गतिशील रूप से एक चर कंटेनर वर्ग में बनाएंगे।

import string 

class Variable(object): 
    def __init__(self, value): 
     self.value = value 
    def __repr__(self): 
     return "<Variable %s>" % self.value 

class Variables(object): 
    def __getattr__(self, n): 
     if n in string.ascii_uppercase: 
      v = Variable(n) 
      setattr(self, n, v) 
      return v 
     raise AttributeError("Variables instance has no attribute %s" % n) 

उपयोग:

>>> v = Variables() 
>>> v.G 
<Variable G> 
>>> v.Y 
<Variable Y> 
>>> v.G is v.G 
True 

सरल और साफ है, कोई बदसूरत हैक्स (अच्छी तरह से, एक getattr को छोड़कर, और यह नहीं है कि बदसूरत है), और तुम भी चर आपके पास करने के लिए की जरूरत नहीं है जरूरत नहीं है

+0

जबकि मैं मानता हूं कि यह आमतौर पर जाने का तरीका है, निश्चित रूप से स्थानीय नामस्थान में बहुत सारी वस्तुओं को जोड़ने के लिए निश्चित रूप से मामलों का उपयोग किया जाता है, उदा। गणित के लिए एक्स == पाप (डब्ल्यू) * (वाई + एक्सपी (-z)) v.x == m.sin (v.w) * (v.y + m.exp (-v.z)) से बेहतर दुनिया है। – DSM

+0

ठीक है, मुझे लगता है कि एक पत्र के साथ गणितज्ञ जुनून एक लंबे समय तक परिवर्तनीय नाम पहली जगह में एक गलती है। :) यह उपयोगी होता है जब आप कागज़ पर अपनी गणना करते हैं, या सूत्रों को सरल/विस्तृत करते हैं। लेकिन एक प्रोग्रामिंग भाषा में एक सूत्र के वास्तविक कार्यान्वयन में? न्याहहम संदेहजनक है ... :-) –

+2

शायद आप तुरंत "v।" को हटा सकते हैं और "एम।" मेरी दूसरी अभिव्यक्ति में और पहली अभिव्यक्ति देखें, लेकिन मुझे यह सुनिश्चित करने के लिए चरित्र के लगभग चरित्र की तुलना करना था कि वे वही थे। प्रत्येक चर और फ़ंक्शन के लिए एक अतिरिक्त अक्षर, और एक बिंदु जो मुझे गुणा सोचता है। मुझे दूसरे रूप में एक स्पष्ट त्रुटि को याद करने की अधिक संभावना है, क्योंकि मुझे मानक रूप पढ़ने के वर्षों के अनुभव को दूर करना है, बिना बाहरी वर्णों के। पठनीयता की गणना करता है, जैसा कि मैंने सुना है कि किसी ने कहीं कहा है ;-), और वह सिद्धांत हमेशा अधिक पात्रों के पक्ष में झुका नहीं जाता है। – DSM

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