2017-07-03 20 views
0

如果我是正確的:sys._getframe()。f_builtins和__builtins __.__ dict__等價嗎?

  • sys._getframe().f_builtins在當前調用堆棧的頂部框架內置的對象;和

  • __builtins__.__dict__是當前模塊中的內建對象。

sys._getframe().f_builtins__builtins__.__dict__的值有什麼不同?他們總是有相同的價值,即相同的內建物件?

回答

2

sys._getframe().f_builtins__builtins__.__dict__的值有什麼不同?他們總是有相同的價值,即相同的內建物件?

是的。

Python中的內建名稱在作用域和名稱空間中保持不變。這就是爲什麼他們叫「builtins」;你可以從任何地方訪問它們,因爲它們是內置在解釋器中的。除非你明確地改變了內建映射,否則它們將是相同的。

但不僅如此,他們都指向相同 builtins映射。這意味着對__builtins__.__dict__的更改將改變sys._get_frame().f_builtins,反之亦然。

這也可以通過一個簡單的例子來測試:

>>> import sys 
>>> frame = sys._getframe() 
>>> 
>>> frame.f_builtins == __builtins__.__dict__ 
True 
>>> frame.f_builtins['abc'] = 3 
>>> frame.f_builtins['abc'] 
3 
>>> frame.f_builtins == __builtins__.__dict__ 
True 
>>> 

當我們添加一個新的內置名frame.f_builtins__builtins__.__dict__改變了。

注意:__builtins__是CPython的實現細節,在其他Python實現中可能不存在。所以不要依賴它。相反,請使用builtins模塊。

+0

謝謝。 'frame.f_builtins == __builtins __.__ dict__'中的== ==檢查兩個操作數綁定到同一個對象,還是檢查綁定到兩個操作數的對象是否具有相同的值/內容? – Tim

+0

@Tim它會比較「dict」是否具有相同的內容。您可以通過創建兩個具有相同內容的字典對象並查看它們是否相等來嘗試。 –

1

我不知道任何情況下,執行框的內置(通過其f_builtins屬性評估)將不同於訪問__builtin__模塊。但是,需要注意的是,如果您有一些自定義代碼處理它,則f_builtins可能會有所不同。

根據this source

的直接訪問的方式是使用eval()或exec和指定與建宏構件 '全局' 字典。如果存在,此 將成爲代碼的內置函數,以f_builtins的形式顯示在框架中, 等等。對於f_builtins,具有非標準值的任何代碼幀都是 「受限制」的幀,並且CPython內部的各個位以不同的方式表現 (通常它們禁止各種操作,例如 設置類的屬性)。反過來,所有這些似乎都是 目前支持現在不推薦使用的rexec。py模塊,它試圖 (你猜對了)限制了一些不可信的Python代碼可以做的事情。