如果你已經學習了包,模組這些知識了。
你會不會有好奇:Python為什麼可以直接使用一些內建函數,不用顯式的匯入它們,比如 str() int() dir() ...?
原因是Python解譯器第一次啟動的時候 __builtins__ 就已經在命名空間了(Note: 有s)
進Shell看看:
>>> globals(){'__builtins__': , '__name__': '__main__', '__doc__': None, '__package__': None}
你可以再次匯入 __builtin__(Note: 沒有s):
import __builtin__>>> globals(){'__builtins__': , '__name__': '__main__', '__doc__': None, '__builtin__': , '__package__': None}
這時候多了一個 __builtin__ 對象,你可以判斷它們是不是相同的:
>>> __builtin__ is __builtins__True>>> type(__builtin__)>>> type(__builtins__)
現在我們把它從一個檔案匯入:
# file1.pyimport __builtin__print "module name __name__ : ", __name__print "__builtin__ is __builtins__: ", __builtin__ is __builtins__print "type(__builtin__): ", type(__builtin__)print "type(__builtins__): ", type(__builtins__)print "__builtins__ is __builtin__.__dict__", __builtins__ is __builtin__.__dict__# file2.pyimport file1"""結果:module name __name__ : file__builtin__ is __builtins__: Falsetype(__builtin__): type(__builtins__): __builtins__ is __builtin__.__dict__ True"""
結論:
__builtins__ 是對內建模組 __builtin__ 的引用,並且有如下兩個方面差異:
在主模組中,即沒有被其他檔案匯入。__builtins__是對 __builtin__ 本身的引用,兩者是相同的。
通過 __builtins__ is __builtin__.__dict__ 猜想:
在非 '__main__' 模組中,也就是模組被匯入後,__builtins__ 應該屬於 __builtin__.__dict__ 的一部分,是對 __builtin__.__dict__ 的引用,而非builtin本身,它在任何地方都可見,此時builtins的類型是字典。
裝飾內建函數
Python 官方文檔 解釋了如何裝飾一個內建函數:
import __builtin__def open(path): f = __builtin__.open(path, 'r') return UpperCaser(f)class UpperCaser: __metaclass__ = type def __init__(self, f): self._f = f def read(self): return self._f.read().upper()print open('./a.txt').read()# 將會全部轉為大寫輸出
Note:Python3.X版本中,內建模組更名為builtins,與Python2.X有所不同