2014-02-14 49 views
2

這可能以前曾被問到過,但快速搜索沒有給我一個答案。Python:在函數的本地命名空間中包含詞典條目

假設有一個包含所有變量的字典。我如何將這個字典傳遞給函數的本地名稱空間?例如:

data = dict(a=1,b=2,c=3,d=4) 
def f(data): 
    return data['a'] + data['d'] 

要求在每個想要訪問的變量周圍寫入數據['']。如何將字典的所有條目添加到函數的本地名稱空間?對於對象,你可以使用

self.__dict__.update(data) 

有什麼等價物的功能,讓你得到的線沿線的東西:

data = dict(a=1,b=2,c=3,d=4) 
def f(data): 
    add_to_local_namespace(data) 
    return a + d 
+0

我有這個問題是爲什麼?這似乎是非pythonic。如果你想要他們的值,爲什麼不傳遞字典索引作爲參數呢? –

+0

@DylanLawrence該字典還將用作函數中進一步對類對象的輸入。由於在類中使用了不少變量,我不想在創建對象時將它們全部寫下來。正如我從另一個包含輸入的模塊調用這些函數,我需要通過所有的輸入。 – Forzaa

+0

字典是一個可變對象,你在函數內部改變的東西會反映原來的,就像在Python中它通過對象引用一樣。 –

回答

5

它在一般情況下是不可能的,因爲字典可以有鑰匙這些不是有效的變量名稱,例如Python keywords或非字符串。

如果你非常需要這個,你可以保證字典鍵都是有效的變量名,,你不需要它在Python 3上工作,可以遍歷字典項並使用exec聲明。這種方法有一些奇怪的範圍結果,這很醜陋,應該強烈勸阻。

可接受的替代方法是創建一個虛擬對象,並將它們設置爲屬性,例如:

>>> data = dict(a=1,b=2,c=3,d=4) 
>>> from types import SimpleNamespace 
>>> v = SimpleNamespace(**data) 
>>> v.a 
1 
>>> v.d 
4 

但這只是真的很喜歡字典訪問的語法糖。 閱讀Python的禪#19。無論你如何看待它,你都需要命名空間!

另一個想法:創建一個可調用的類而不是一個函數(通過繼承collections.Callable),並將dict解包爲該類的屬性。那麼至少你的變量將被類命名空間。

+0

這可能是最合適的解決方案,因爲它不需要惡意的黑客或明確地寫下該函數中使用的所有變量。 – Forzaa

+0

這是一個非常酷的想法。 +1。我認爲你仍然可能需要小心可變對象。 –

+0

以下是證據:'import argparse; d = {'a':[1]}; o = argparse.Namespace(** d); o.a.append('no no no no no'); d ['a']'返回'[1,'no no no no no']'' –

相關問題