如何理解Python中包的引入
Python的from import *和from import *,它們的功能都是將包引入使用,但是它們是怎么執(zhí)行的以及為什么使用這種語法呢?
從一模塊導(dǎo)入全部功能
from import * means意味著“我希望能訪問中我有權(quán)限訪問的全部名稱”。例如以下代碼something.py:
# something.pypublic_variable = 42_private_variable = 141def public_function(): print('I’m a public function! yay!')def _private_function(): print('Ain’t nobody accessing me from another module...usually')class PublicClass(object): passclass _WeirdClass(object): pass
在Python解釋器中,我們可以執(zhí)行from something import *,然后看到如下的內(nèi)容:
>>> from something import *>>> public_variable42>>> _private_variable...NameError: name ’_private_variable’ is not defined>>> public_function()'I’m a public function! yay!'>>> _private_function()...NameError: name ’_private_function’ is not defined>>> c = PublicClass()>>> c<something.publicclass object='' at='' ...=''>>>> c = _WeirdClass()...NameError: name ’_WeirdClass’ is not defined
from something import *從something中導(dǎo)入了除了以_開頭名稱外的其他所有名稱,按照規(guī)范,_開始的名稱是私有的所以未被導(dǎo)入。
上面沒提到__all__是什么。__all__是一個字符串列表,指定了當(dāng)from import *被使用時,模塊(或者如后文會提到的包)中的哪些符號會被導(dǎo)出。如果我們不定義__all__(我們在上面的something.py就沒定義),import *默認的導(dǎo)入方式是導(dǎo)入除了下劃線(_)開頭的所有名稱。再說一次,編程慣例上下劃線表示一個符號是私有的,不導(dǎo)入是合理的。讓我們來看看在something.py中定義我們自己的__all__會發(fā)生什么。
# something.py__all__ = [’_private_variable’, ’PublicClass’]# The rest is the same as beforepublic_variable = 42_private_variable = 141def public_function(): print('I’m a public function! yay!')def _private_function(): print('Ain’t nobody accessing me from another module...usually')class PublicClass(object): passclass _WeirdClass(object): pass
現(xiàn)在,我們期望from something import *只會導(dǎo)入_private_variable和PublicClass:
# something.py__all__ = [’_private_variable’, ’PublicClass’]# The rest is the same as beforepublic_variable = 42_private_variable = 141def public_function(): print('I’m a public function! yay!')def _private_function(): print('Ain’t nobody accessing me from another module...usually')class PublicClass(object): passclass _WeirdClass(object): pass
包是怎樣的呢?
當(dāng)從一個包中導(dǎo)入全部時,__all__的做法和模塊基本一樣,不過它處理的是包中的模塊(而不是把模塊中的名都導(dǎo)入)。所以當(dāng)我們使用from import *.時__all__說明了所有需要被導(dǎo)入當(dāng)前命名空間的模塊。
不同之處在于,如果你在一個包的__init__.py里面沒有聲明__all__,from import *語句不會導(dǎo)入任何東西(這個說法也不全對,正確的說法在此)
但是,這有什么不好?
繼續(xù)讀之前,在你的Python解釋器中,執(zhí)行import this,再讀一遍Python之禪(在你孩子每晚睡前也要讀給他們)。
明確比含糊要好。
from import * 是不明確的。它沒告訴我們我們正在導(dǎo)入什么或者我們把什么帶入當(dāng)前命名空間了。更好的做法是顯式地導(dǎo)入我們需要的全部名稱。這種方式下,讀者(非常可能是未來的你自己)就不會困惑于你代碼中使用的一個變量/方法/類/其他東西是哪兒來的,這也告訴了我們下一點:
可讀性很重要
即使你需要導(dǎo)入很多東西,一個一個顯式地導(dǎo)入也更清楚。使用PEP 328:
from Tkinter import (Tk, Frame, Button, Entry, Canvas, Text, LEFT, DISABLED, NORMAL, RIDGE, END)
你現(xiàn)在就能明確知道你的命名空間里有什么,使用ctrl+f能很快地告訴你它們是哪兒來的。
同時,你還總是要承擔(dān)模塊/包作者更改list內(nèi)容(加/減東西)的風(fēng)險。
內(nèi)容擴展:
基本注意點
模塊:一般指一個py文件;包:含有許多py文件的文件夾,含有 或不含有(Python3中允許)__init__文件。 凡是在導(dǎo)入時帶點的,點的左邊都必須是一個包 (import a.fun1 其中a為py文件)這種導(dǎo)入形式是錯誤的。 2.from a import fun1 a為一個py文件,fun1為該文件的屬性或方法,這種導(dǎo)入形式是可以的。 一般來說 import 后面不能帶點,如:(from a import b.c是錯誤語法) 導(dǎo)入模塊時,是將模塊的py文件導(dǎo)入進去(執(zhí)行);導(dǎo)入包時,只會執(zhí)行包中的__init__文件中的代碼,故導(dǎo)入包時一般要導(dǎo)入到最底層,即from dir1.dir2.dir3 import py文件或者類、方法、屬性,只有這樣才能找到。但是你可以通過先導(dǎo)入一個包,然后在包的文件中的__init__中寫相關(guān)的import語句(可以絕對,也可以相對),這樣也可以通過import 包名 的方式將包中的東西導(dǎo)入進去。以上就是如何理解Python中包的引入的詳細內(nèi)容,更多關(guān)于Python中包的引入詳解的資料請關(guān)注好吧啦網(wǎng)其它相關(guān)文章!
相關(guān)文章:
1. 使用 kind 和 Docker 啟動本地的 Kubernetes環(huán)境2. jsp中sitemesh修改tagRule技術(shù)分享3. Docker究竟是什么 為什么這么流行 它的優(yōu)點和缺陷有哪些?4. docker容器調(diào)用yum報錯的解決辦法5. IntelliJ IDEA導(dǎo)出項目的方法6. Django中如何使用Channels功能7. idea設(shè)置代碼格式化的方法步驟8. python的json包位置及用法總結(jié)9. Python通過zookeeper實現(xiàn)分布式服務(wù)代碼解析10. 關(guān)于html嵌入xml數(shù)據(jù)島如何穿過樹形結(jié)構(gòu)關(guān)系的問題

網(wǎng)公網(wǎng)安備