Python __init__.py 做用詳解

__init__.py 文件的做用是將文件夾變爲一個Python模塊,Python 中的每一個模塊的包中,都有__init__.py 文件。python

一般__init__.py 文件爲空,可是咱們還能夠爲它增長其餘的功能。咱們在導入一個包時,其實是導入了它的__init__.py文件。這樣咱們能夠在__init__.py文件中批量導入咱們所須要的模塊,而再也不須要一個一個的導入。函數

# package
# __init__.py
import re
import urllib
import sys
import os

# a.py
import package 
print(package.re, package.urllib, package.sys, package.os)

注意這裏訪問__init__.py文件中的引用文件,須要加上包名。url

__init__.py中還有一個重要的變量,__all__, 它用來將模塊所有導入。調試

# __init__.py
__all__ = ['os', 'sys', 're', 'urllib']

# a.py
from package import *

這時就會把註冊在__init__.py文件中__all__列表中的模塊和包導入到當前文件中來。code

能夠了解到,__init__.py主要控制包的導入行爲。要想清楚理解__init__.py文件的做用,還須要詳細瞭解一下import語句引用機制:對象

能夠被import語句導入的對象是如下類型:ip

  • 模塊文件(.py文件)
  • C或C++擴展(已編譯爲共享庫或DLL文件)
  • 包(包含多個模塊)
  • 內建模塊(使用C編寫並已連接到Python解釋器中)

當導入模塊時,解釋器按照sys.path列表中的目錄順序來查找導入文件。unicode

import sys
>>> print(sys.path)

# Linux:
['', '/usr/local/lib/python3.4',
 '/usr/local/lib/python3.4/plat-sunos5',
 '/usr/local/lib/python3.4/lib-tk',
 '/usr/local/lib/python3.4/lib-dynload',
 '/usr/local/lib/python3.4/site-packages']

# Windows:
['', 'C:\\WINDOWS\\system32\\python34.zip', 'C:\\Documents and Settings\\weizhong', 'C:\\Python34\\DLLs', 'C:\\Python34\\lib', 'C:\\Python34\\lib\\plat-win', 'C:\\Python34\\lib\\lib-tk', 'C:\\Python34\\Lib\\site-packages\\pythonwin', 'C:\\Python34', 'C:\\Python34\\lib\\site-packages', 'C:\\Python34\\lib\\site-packages\\win32', 'C:\\Python34\\lib\\site-packages\\win32\\lib', 'C:\\Python34\\lib\\site-packages\\wx-2.6-msw-unicode']

其中list第一個元素空字符串表明當前目錄。文檔

關於.pyc 文件 與 .pyo 文件字符串

.py文件的彙編,只有在import語句執行時進行,當.py文件第一次被導入時,它會被彙編爲字節代碼,並將字節碼寫入同名的.pyc文件中。後來每次導入操做都會直接執行.pyc 文件(當.py文件的修改時間發生改變,這樣會生成新的.pyc文件),在解釋器使用-O選項時,將使用同名的.pyo文件,這個文件去掉了斷言(assert)、斷行號以及其餘調試信息,體積更小,運行更快。(使用-OO選項,生成的.pyo文件會忽略文檔信息)

導入模塊

模塊一般爲單獨的.py文件,能夠用import直接引用,能夠做爲模塊的文件類型有.py、.pyo、.pyc、.pyd、.so、.dll

在導入模塊時,解釋器作如下工做:

  1. 已導入模塊的名稱建立新的命名空間,經過該命名空間就能夠訪問導入模塊的屬性和方法。

  2. 在新建立的命名空間中執行源代碼文件。

  3. 建立一個名爲源代碼文件的對象,該對象引用模塊的名字空間,這樣就能夠經過這個對象訪問模塊中的函數及變量

import 語句能夠在程序的任何位置使用,你能夠在程序中屢次導入同一個模塊,但模塊中的代碼僅僅在該模塊被首次導入時執行。後面的import語句只是簡單的建立一個到模塊名字空間的引用而已。

sys.modules字典中保存着全部被導入模塊的模塊名到模塊對象的映射。

導入包

多個相關聯的模塊組成一個包,以便於維護和使用,同時能有限的避免命名空間的衝突。通常來講,包的結構能夠是這樣的:

package
  |- subpackage1
      |- __init__.py
      |- a.py
  |- subpackage2
      |- __init__.py
      |- b.py

有如下幾種導入方式:

import subpackage1.a # 將模塊subpackage.a導入全局命名空間,例如訪問a中屬性時用subpackage1.a.attr
from subpackage1 import a # 將模塊a導入全局命名空間,例如訪問a中屬性時用a.attr_a
from subpackage.a import attr_a # 將模塊a的屬性直接導入到命名空間中,例如訪問a中屬性時直接用attr_a

使用from語句能夠把模塊直接導入當前命名空間,from語句並不引用導入對象的命名空間,而是將被導入對象直接引入當前命名空間。

相關文章
相關標籤/搜索