Python的模塊引入

環(huán)境:

大部分在Python3.7下測試執(zhí)行

import語句很長時該怎么書寫

可以:

from Tkinter import Tk, Frame, Button, Entry, Canvas, Text, \
    LEFT, DISABLED, NORMAL, RIDGE, END

也可以:

from Tkinter import Tk, Frame, Button, Entry, Canvas, Text
from Tkinter import LEFT, DISABLED, NORMAL, RIDGE, END

但官方建議使用括號:

from Tkinter import (Tk, Frame, Button, Entry, Canvas, Text,
    LEFT, DISABLED, NORMAL, RIDGE, END)

模塊查找順序

  1. 先搜索內(nèi)置模塊(built-in module,內(nèi)置在python編譯器),如winreg模塊(或叫_winreg模塊,只在Windows下存在)
  2. sys.path(list類型)指定的一個個目錄里搜索。

關(guān)于sys.path

執(zhí)行python script.py時,sys.path的第一個元素是script.py文件所在的目錄;如果不指定腳本文件,如;直接執(zhí)行python進(jìn)入交互模式,或執(zhí)行python -m expectd.package.module等,sys.path的第一個元素就是空字符串,代表執(zhí)行python命令時所在的目錄。

sys.path還包括PYTHONPATH環(huán)境變量指定的目錄,和安裝時指定的默認(rèn)值(The installation-dependent default)

絕對引入

一個目錄結(jié)構(gòu)為:

package/
    __init__.py
    string.py
    test.py

test.py里寫import string,然后在package/目錄的上一層目錄(以讓python找到我們自己寫的package的位置)執(zhí)行python -m package.test,那import的是同目錄下的string模塊,還是python自帶的string模塊呢?

在Python2.7下測試,是引入同目錄下的string模塊,因?yàn)?code>import string語句會先查找同目錄下的模塊。這樣的引入方式,無法在不重命名package/string.py文件的情況下導(dǎo)入python自帶的string模塊。所以Python加了一個絕對引入(absolute import),且在python3中默認(rèn)使用,而在Python 2中使用絕對引入,需要在文件頭寫:from __future__ import absolute_import。

絕對引入是指import時,都是從sys.path指定的目錄下查找包或模塊。如:import foo,from foo import bar。有了絕對引入,那要引入同目錄下的模塊,需要加上.符號,這叫相對引入(relative import, 相對于當(dāng)前模塊來引入)。如:from .foo import bar。而要引入上一層的模塊,就用兩個點(diǎn),要引入上上一層就用三個點(diǎn),如:from ..foo import bar引入上一層的模塊。另外,要引入上一層的模塊時,不可以寫成import ..foo,而是寫成from .. import foo。

所以上面在python3測試,是引入python自帶的string模塊,若要引入同目錄下的string模塊,就寫成from . import string

__init__.py文件

在目錄下有__init__.py文件,Python才會把該目錄看作包(package),在該文件中可以寫初始化代碼(引入包或包里模塊等時會執(zhí)行__init__.py),也可以設(shè)置__all__變量。

一個包的目錄結(jié)構(gòu)為:

package/
    __init__.py
    moduleX.py
    moduleY.py

如果__init__.py文件的__all__變量沒設(shè)置,執(zhí)行from package import *import package并不會引入package下的子模塊或子包,而僅僅是引入該包(一般會執(zhí)行__init__.py的代碼)。需要這樣寫from package import moduleX, moduleY,就可以引入模塊。

如果__init__.py文件里寫__all__ = ['moduleX', 'moduleY'],執(zhí)行from package import *就會引入__all__里的模塊或子包,也就是會在當(dāng)前域中存在moduleXmoduleY變量。

python script

有些時候并不是要寫一個模塊供調(diào)用,而是寫幾個腳本來執(zhí)行。

目錄結(jié)構(gòu)為:

my_scripts/
    sub/
        __init__.py
        fibo.py
    helper.py
    test.py

(因?yàn)橐?code>test.py文件中引入sub/fibo.py,需要告訴Python sub目錄是個包,所以要放置__init__.py文件)

test.py里引入

import helper
from sub import fibo

然后在my_scripts/目錄下執(zhí)行python test.py??梢砸?,沒有報(bào)錯。這是為什么?

像上面說的,sys.path的第一個元素是test.py所在的目錄,所以上面兩個絕對引入是可以找得到helperfibo的。

python -m命令

模塊除了被import,也可以直接用python -m命令把模塊當(dāng)腳本來執(zhí)行。如:python -m json.tool執(zhí)行json包里的tool模塊,用來格式化JSON數(shù)據(jù)。還有python -m pdb script.py、python -m profile script.py等。

python -m命令,實(shí)際上是調(diào)用runpy模塊的runpy.run_module(mod_name, init_globals=None, run_name=None, alter_sys=False)方法,其會搜索模塊,依據(jù)加載的包、模塊名來設(shè)置__package__屬性等,以便讓相對引入正確執(zhí)行。例如執(zhí)行python -m json.tool時,__name__設(shè)置成json.tool,__package__設(shè)置成"json.tool".rpartition('.')[0],即json。

參考鏈接

其它

from fibo import *

fibo是個模塊,該import會導(dǎo)入fibo模塊下所有變量,除了以_開頭的變量。

dir()不會列出內(nèi)置函數(shù)和內(nèi)置變量,如果想要獲取內(nèi)置函數(shù)和內(nèi)置變量,使用import builtins; dir(builtins)

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容