Python-__builtin__與__builtins__的區別與關係(超詳細,經典)(轉)

Python-__builtin__與__builtins__的區別與關係(超詳細,經典)

  (2013-07-23 15:27:32)
  分類: Python

在學習Python時,不少人會問到__builtin__、__builtins__和builtins之間有什麼關係。百度或Google一下,有很 多答案,可是這些答案要麼不許確,要麼只說了一點點,並不全面。本文將給你們一個較爲全面的答案。如下結果是通過本人試驗過的(測試環境:Linux Mint 14, Python2.7.3和Python3.2.3),並參考了Python的郵件列表。html

Python中,有一個內建模塊,該模塊中有一些經常使用函數;而該模塊在Python啓動後、且沒有執行程序員所寫的任何代碼前,Python會首先加載 該內建函數到內存。另外,該內建模塊中的功能能夠直接使用,不用在其前添加內建模塊前綴,其緣由是對函數、變量、類等標識符的查找是按LE(N)GB法 則,其中B即表明內建模塊。好比:內建模塊中有一個abs()函數,其功能是計算一個數的絕對值,如abs(-20)將返回20。程序員

Python2.X版本中,內建模塊被命名爲__builtin__,而到了Python3.X版本中,卻改名爲builtins函數

當使用內建模塊中函數或其它功能時,能夠直接使用,不用添加內建模塊的名字;可是,若是想要向內建模塊中添加一些功能,以便在任何函數中都能直接使用而不 用再進行import,這時,就要導入內建模塊,在內建模塊的命名空間(即__dict__字典屬性)中添加該功能。在導入時,若是是Python2.X 版本,就要導入__builtin__模塊;若是是Python3.X版本,就要導入builtins模塊。如:在Python2.X中,向內建模塊添加 一個函數(該函數打印「hello, world」),能夠這樣寫(如下的用法是在主模塊中的使用,其它模塊請看下面):學習

import __builtin__測試

def print_hello():ui

print "hello, world"spa

__builtin__.__dict__['hello'] = print_hello3d

print_hello() # 將打印"hello, world"htm

hello() # 將打印"hello, world"blog

此時,print_hello和hello兩個函數名幾乎是同樣,可是有一點區別,print_hello只能在該模塊中使用,而hello能夠在本程序中的其它任何一個模塊中使用,由於hello已經放到內建模塊中了。

如今,__builtin__和builtins之間的關係已經說清楚了,如今該說說__builtins__了。爲了統一Python2.X和Python3.X,在下面的論述中,內建模塊一概統稱爲__builtin__。

由上面的論述,咱們知道,__builtin__存在於Python2.X中,而builtins存在於Python3.X中,可是對於 __builtins__,它卻同時存在於Python2.X和Python3.X中。那麼它究竟是什麼東西呢?由名字可知,它確定與內建模塊有關。其實 簡單地說,它就是對內建模塊一個引用。

一、__builtins__便是引用,那麼它內建模塊有一個相同點:Python程序一旦啓動,它們兩者就會在程序員所寫的代碼沒有運行以前就已經被加載到內存中了。

二、雖是一個引用,但__builtins__和內建模塊是有一點區別的:

(1)不管任何地方要想使用內建模塊,都必須在該位置所處的做用域中導入__builtin__內建模塊;而對於__builtins__卻不用導入,它在任何模塊都直接可見, 能夠把它看成內建模塊直接使用(這句並不徹底正確,請看第(2)點)。即:__builtins__在任何地方、任何模塊均可見,而內建模塊名只在相應的 做用域中被import後才能夠(該import並非把內建模塊加載到內存中——內建早已經被加載了,它僅僅是讓內建模塊名在該做用域中可見)。

(2)__builtins__雖是對內建模塊的引用,但這個引用要看是使用__builtins__的模塊是哪一個模塊:

1】 在主模塊__main__中:

__builtins__是對內建模塊__builtin__自己的引用,即__builtins__徹底等價於__builtin__,兩者徹底是一個東西,不分彼此。它在任何地方均可見,即在任何地方均可使用它。此時,__builtins__的類型是模塊類型。

__builtin__僅僅在導入它時纔可見。哪一個做用域中使用__builtin__,哪一個做用域就要導入它(導入僅僅是讓__builitin__標 識符在該做用域內可見)。通常都是在模塊的頂層(即模塊的全局做用域)導入__builtin__,這樣,其後的任何做用域可經過標識符向上查找來引用 __builtin__。

2】在非__main__模塊中:

__builtins__僅是對__builtin__.__dict__的引用,而非__builtin__自己。它在任何地方均可見。此時__builtins__的類型是字典。

__builtin__和在主模塊中的狀況同樣。

由上面的異同,咱們能夠出,__builtins__、__builtin__和builtins之間並無太大的不一樣;在使用__builtins__時,只要注意其引用的究竟是__builtin__仍是__builtin__.__dict__便可。

此時,可能會有人說,既然__builtin__和builtins因爲Python版本的不一樣而不一樣,致使在寫兼容2.X和3.X版本時的代碼時比較麻 煩,而__builtins__在2.X和3.X中都是同樣的,那麼,再也不使用builtins和__builin__,改用__builtins__不 是更好?!這種作法並無錯,可是有一點,在使用__builtins__時,要區分是在主模塊__main__中,仍是在其餘的非__main__模塊 中。筆者看了Python標準庫(好比gettext),其中使用的是__builtin__(在Python2.X中)和builtins(在 Python3.X中),而並無使用__builtins__。這僅僅給一些參考。

說明:

主模塊__main__:在Python中,一個代碼文件就是一個模塊,一個模塊就是一個代碼文件;用來啓動Python或者說首先執行的那個文件(至關 於C語言中main主函數所在的C文件)的模塊名被Python命名爲__main__,稱爲主模塊,而對於其它被主模塊或其餘非主模塊導入的模塊,它們 的模塊名則是文件名自己(除了後綴.py、.pyc或.pyo等)。每一個模塊都有一個名爲__name__的屬性,它表示着該模塊的名字。除此以外,主模 塊與其它非主模塊之間還有一點區別,好比:from __future__ import absolute_import語句在非主模塊中能夠正常使用,反而在主模塊中,好像沒有什麼效果——有等無。

相關文章
相關標籤/搜索