2013-02-08 100 views
2

大多數人可能會說這是一個糟糕的主意。我想使用字符串的內容作爲變量的名稱。我想要完成的可怕:用字符串設置python對象/變量的名稱

s = 'x' 
x = 1 

其中變量名x從字符串s來(不知何故?)。

要回答「爲什麼?」,說我有一個x的全局默認值,我希望在函數中覆蓋選項。但是:

x = 0 
def f(**kw): 
    print x 
f(x=1) 

打印01。如果我可以使用kw.keys()中的字符串重新分配x(或任何其他全局變量),那麼我會很高興。

我意識到,這適用於在f重新分配x

x = 0 
def f(x=x): 
    print x 
f(x=1) 

但我想爲那裏有我的名字空間許多變數,我可能會在某個時候要重寫而無需重寫每一個案件做到這一點函數定義在我的模塊中。

+2

爲什麼不把這些「全球性」的狀態變量的字典? – pawroman

回答

3

退房exec

>>> print x 
Traceback (most recent call last): 
    File "<stdin>", line 1, in <module> 
NameError: name 'x' is not defined 
>>> s = 'x' 
>>> exec(s + " = 1") 
>>> print x 
1 

參見:How can I assign the value of a variable using eval in python?

一個小實驗後,這也似乎工作:

>>> print x 
Traceback (most recent call last): 
    File "<stdin>", line 1, in <module> 
NameError: name 'x' is not defined 
>>> s = 'x' 
>>> globals()[s] = 1 
>>> print x 
1 
+1

幾乎沒有理由使用eval或exec。在這種情況下,您可以使用getattr或setattr。 – Keith

+0

對於我自己的學習,如何在這種情況下使用setattr? –

+0

您編輯的答案是直接設置全局變量的一種方法。但我通常保留全局變量(只讀)的全局變量。如果你需要保持狀態,那麼使用類和實例變量。 – Keith

1

通過函數參數賦值並不明顯,因此不被視爲Pythonic(Python不是C)。見import this

,我已經做了扁平結構的廉價的方式是通過一個全球性的局部字典:

In [1]: from functools import partial 
In [2]: config = partial(dict) 
In [3]: def f(x=None): 
    ...:  print x or config.x 
    ...:  
In [4]: config.x = 'foo' 
In [5]: f() 
foo 

東西這種效果明顯,可讀性強,因此更容易維護。

1

但我想這樣做的情況下,我的名字空間中有很多變量,我可能在某些時候想要重寫而不重寫我的模塊中的每個函數定義。

這聽起來像你想有一個類:

class Foo(object): 
    x = 0 
    def f(self): 
     print self.x 

my_foo = Foo() 
my_foo.x = 1 
my_foo.f() 
+0

我相信你是對的,這是最好的大圖解答。我知道我需要學習如何在代碼中使用類。所以考慮到我在一個具有許多不同交互函數的模塊中完成所有這些工作,我想我應該將所有這些相關函數包裝在一個類中,以更好地控制它們共享的參數。我想這會避免或至少有助於解決所有這些函數必須來回傳遞參數的問題。 –