在閱讀with
聲明(link)的規範時,我有一些我想玩的東西。這不適用於任何生產代碼或任何東西,我只是在探索,所以如果這是一個壞主意,請不要太苛刻。獲取要在語句中執行的命令塊
我想要做的是在上面的鏈接文檔中抓取名爲「BLOCK」的作品,並在__enter__
的調用中實際修補它。 (請參閱鏈接文檔,在激勵和摘要部分開始之後)。
這個想法是創建我自己的即時本地命名空間。事情是這樣的:
with MyNameSpace(some_object):
print a #Should print some_object.a
x = 4 #Should set some_object.x=4
基本上,我想with
塊中的語句是從屬於局部變量和some_object
分配慣例。
在我的具體情況下,some_object
可能是一個特殊的數據陣列,它具有我自己的按列操作或其他內容。在這種情況下,像x = y + 5 if y > 4 else y - 2
這樣的內容可能是一些奇妙的NumPy向量化操作,但我不需要明確地調用some_object
的這些方法的接口。在命名空間中,表述應該「只是工作」(但是我確定他們在MyNameSpace
類來推斷。
我的第一個想法是莫名其妙中斷with
過程和獲取雲在try
代碼保持然後在調用__enter__
時解釋該代碼,並用其他內容替換try
塊中的代碼(如果可以,則可能爲pass
,但可能會將some_object
恢復爲原始變量作用域並保留其新的已更改變量)。
一個簡單的測試案例會是這樣的:
my_dict = {'a':3, 'b':2}
with MyNameSpace(my_dict):
print a # Should print 3
x = 5 # When the block finishes, my_dict['x'] should now be 5
我很感興趣,如果這個想法已經存在的地方。
我知道分配變量的最佳做法。這是一個寵物項目,所以請假定,僅僅爲了這個想法,我們可以忽略最佳實踐。即使你不喜歡用這種方式分配變量,它也可能對我當前的項目有用。
編輯
爲了澄清我可能要做好各種棘手的問題,並解決以下聲稱它不能做的答案,可以考慮下面的示例文件testLocals.py
:
my_dict = {'a':1, 'b':2}
m = locals()
print m["my_dict"]['a']
m["my_dict"]['c'] = 3
print my_dict
class some_other_scope(object):
def __init__(self, some_scope):
x = 5
g = locals()
some_scope.update(g)
some_scope["my_dict"]["d"] = 4
sos = some_other_scope(m)
print my_dict
print x
這給當我運行它非交互如下:
[email protected]:~/Desktop/Programming/Python$ python testLocals.py
1
{'a': 1, 'c': 3, 'b': 2}
{'a': 1, 'c': 3, 'b': 2, 'd': 4}
5
你可以使用'with'而不指定(使用'with x as f'或'with x = f')? –
是的,它只是調用上下文管理器的'__enter__'函數等。如果你沒有在塊內引用'with'後面的東西,那麼它就不需要那個東西的名字。 – ely
你可以用當前棧幀中的'globals'字典來猴子,但最根本的問題是它不能在函數內部工作。當一個函數被編譯爲字節碼並以流線形式處理局部變量以獲得更好的性能時,Python會靜態地確定哪些變量是本地變量。 – kindall