如何理解Python中包的引入
Python的from import *和from import *,它們的功能都是將包引入使用,但是它們是怎么執(zhí)行的以及為什么使用這種語(yǔ)法呢?
從一模塊導(dǎo)入全部功能
from import * means意味著“我希望能訪問(wèn)中我有權(quán)限訪問(wèn)的全部名稱”。例如以下代碼something.py:
# something.py public_variable = 42 _private_variable = 141 def 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): pass class _WeirdClass(object): pass
在Python解釋器中,我們可以執(zhí)行from something import *,然后看到如下的內(nèi)容:
>>> from something import * >>> public_variable 42 >>> _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)入。
上面沒(méi)提到__all__是什么。__all__是一個(gè)字符串列表,指定了當(dāng)from import *被使用時(shí),模塊(或者如后文會(huì)提到的包)中的哪些符號(hào)會(huì)被導(dǎo)出。如果我們不定義__all__(我們?cè)谏厦娴膕omething.py就沒(méi)定義),import *默認(rèn)的導(dǎo)入方式是導(dǎo)入除了下劃線(_)開頭的所有名稱。再說(shuō)一次,編程慣例上下劃線表示一個(gè)符號(hào)是私有的,不導(dǎo)入是合理的。讓我們來(lái)看看在something.py中定義我們自己的__all__會(huì)發(fā)生什么。
# something.py __all__ = ['_private_variable', 'PublicClass'] # The rest is the same as before public_variable = 42 _private_variable = 141 def 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): pass class _WeirdClass(object): pass
現(xiàn)在,我們期望from something import *只會(huì)導(dǎo)入_private_variable和PublicClass:
# something.py __all__ = ['_private_variable', 'PublicClass'] # The rest is the same as before public_variable = 42 _private_variable = 141 def 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): pass class _WeirdClass(object): pass
包是怎樣的呢?
當(dāng)從一個(gè)包中導(dǎo)入全部時(shí),__all__的做法和模塊基本一樣,不過(guò)它處理的是包中的模塊(而不是把模塊中的名都導(dǎo)入)。所以當(dāng)我們使用from import *.時(shí)__all__說(shuō)明了所有需要被導(dǎo)入當(dāng)前命名空間的模塊。
不同之處在于,如果你在一個(gè)包的__init__.py里面沒(méi)有聲明__all__,from import *語(yǔ)句不會(huì)導(dǎo)入任何東西(這個(gè)說(shuō)法也不全對(duì),正確的說(shuō)法在此)
但是,這有什么不好?
繼續(xù)讀之前,在你的Python解釋器中,執(zhí)行import this,再讀一遍Python之禪(在你孩子每晚睡前也要讀給他們)。
明確比含糊要好。
from import * 是不明確的。它沒(méi)告訴我們我們正在導(dǎo)入什么或者我們把什么帶入當(dāng)前命名空間了。更好的做法是顯式地導(dǎo)入我們需要的全部名稱。這種方式下,讀者(非常可能是未來(lái)的你自己)就不會(huì)困惑于你代碼中使用的一個(gè)變量/方法/類/其他東西是哪兒來(lái)的,這也告訴了我們下一點(diǎn):
可讀性很重要
即使你需要導(dǎo)入很多東西,一個(gè)一個(gè)顯式地導(dǎo)入也更清楚。使用PEP 328:
from Tkinter import (Tk, Frame, Button, Entry, Canvas, Text, LEFT, DISABLED, NORMAL, RIDGE, END)
你現(xiàn)在就能明確知道你的命名空間里有什么,使用ctrl+f能很快地告訴你它們是哪兒來(lái)的。
同時(shí),你還總是要承擔(dān)模塊/包作者更改list內(nèi)容(加/減東西)的風(fēng)險(xiǎn)。
內(nèi)容擴(kuò)展:
基本注意點(diǎn)
- 模塊:一般指一個(gè)py文件;包:含有許多py文件的文件夾,含有 或不含有(Python3中允許)__init__文件。
- 凡是在導(dǎo)入時(shí)帶點(diǎn)的,點(diǎn)的左邊都必須是一個(gè)包 (import a.fun1 其中a為py文件)這種導(dǎo)入形式是錯(cuò)誤的。
- 2.from a import fun1 a為一個(gè)py文件,fun1為該文件的屬性或方法,這種導(dǎo)入形式是可以的。
- 一般來(lái)說(shuō) import 后面不能帶點(diǎn),如:(from a import b.c是錯(cuò)誤語(yǔ)法)
- 導(dǎo)入模塊時(shí),是將模塊的py文件導(dǎo)入進(jìn)去(執(zhí)行);導(dǎo)入包時(shí),只會(huì)執(zhí)行包中的__init__文件中的代碼,故導(dǎo)入包時(shí)一般要導(dǎo)入到最底層,即from dir1.dir2.dir3 import py文件或者類、方法、屬性,只有這樣才能找到。但是你可以通過(guò)先導(dǎo)入一個(gè)包,然后在包的文件中的__init__中寫相關(guān)的import語(yǔ)句(可以絕對(duì),也可以相對(duì)),這樣也可以通過(guò)import 包名 的方式將包中的東西導(dǎo)入進(jìn)去。
以上就是如何理解Python中包的引入的詳細(xì)內(nèi)容,更多關(guān)于Python中包的引入詳解的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
Python使用fliecmp實(shí)現(xiàn)比較文件的操作
對(duì)于文件的比較一般有幾種,比如比較文件的內(nèi)容,比較文件的大小,或者直接對(duì)比整個(gè)項(xiàng)目文件,本文就詳細(xì)的介紹這些方法的實(shí)現(xiàn),感興趣的可以了解一下2021-06-06Python一文入門Flask?Blueprint?SQLAlchemy部分詳解
這篇文章主要為大家介紹了Python一文入門Flask?Blueprint?SQLAlchemy部分詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-03-03Python中的函數(shù)參數(shù)(位置參數(shù)、默認(rèn)參數(shù)、可變參數(shù))
這篇文章主要介紹了Python中的函數(shù)參數(shù):位置參數(shù)、默認(rèn)參數(shù)、可變參數(shù)、關(guān)鍵字參數(shù)和命名關(guān)鍵字參數(shù),需要的小伙伴可以參考下面文章內(nèi)容2021-09-09Numpy 將二維圖像矩陣轉(zhuǎn)換為一維向量的方法
今天小編就為大家分享一篇Numpy 將二維圖像矩陣轉(zhuǎn)換為一維向量的方法,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2018-06-06Python3通過(guò)chmod修改目錄或文件權(quán)限的方法示例
這篇文章主要介紹了Python3通過(guò)chmod修改目錄或文件權(quán)限的方法示例,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2020-06-06Python實(shí)現(xiàn)字符串反轉(zhuǎn)的9種方法(最全)
本文主要介紹了Python實(shí)現(xiàn)字符串反轉(zhuǎn)的9種方法,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2023-07-07Python3爬蟲中關(guān)于Ajax分析方法的總結(jié)
在本篇文章里小編給大家整理的是一篇關(guān)于Python3爬蟲中關(guān)于Ajax分析方法的總結(jié),需要的朋友們可以學(xué)習(xí)下。2020-07-07