網(wǎng)站首頁(yè) 編程語(yǔ)言 正文
Part.I 預(yù)備知識(shí)
Chap.I 幾個(gè)概念的區(qū)分
- Python 模塊(Module),是一個(gè) Python 文件,以 .py 結(jié)尾,包含了 Python 對(duì)象定義和 Python 語(yǔ)句。
- Python 包是一個(gè)分層次的文件目錄結(jié)構(gòu),它定義了一個(gè)由模塊及子包,和子包下的子包等組成的 Python 的應(yīng)用環(huán)境。簡(jiǎn)單來(lái)說(shuō),包就是文件夾,但該文件夾下必須存在 __init__.py 文件, 該文件的內(nèi)容可以為空。__init__.py 用于標(biāo)識(shí)當(dāng)前文件夾是一個(gè)包。
- 文件夾:文件夾就是不存在 __init__.py 文件的文件夾。
Chap.II 模塊中的 all 變量
__all__ 是針對(duì)模塊公開(kāi)接口的一種約定,以提供了“白名單”的形式暴露接口。如果定義了__all__,其他文件中使用from xxx import *導(dǎo)入該文件時(shí),只會(huì)導(dǎo)入 __all__ 列出的成員,可以其他成員都被排除在外。
定義 all 需要注意的地方
- __all__ 的形式都是 list類型。如果寫(xiě)成其他類型, pyflakes 等 lint 工具可能無(wú)法識(shí)別。
- 不能動(dòng)態(tài)生成 __all__,如使用列表解析式。__all__ 的作用是定義公開(kāi)接口,需要以字面量的形式顯式寫(xiě)出來(lái)。
- 即使定義了 __all__, 也不應(yīng)該在非臨時(shí)代碼中使用 from xxx import * 語(yǔ)法,或用編程工具模擬 Ruby 的自動(dòng) import。Python 不像 Ruby,沒(méi)有 Module 這類成員,模塊就是命名空間隔離的執(zhí)行者。如果打破了這一層,引入諸多動(dòng)態(tài)因素,生產(chǎn)環(huán)境中跑的代碼就可能充滿不確定性,調(diào)試也會(huì)變得困難。
- 按照 PEP8 建議的風(fēng)格,__all__ 應(yīng)該寫(xiě)在所有 import 語(yǔ)句下面,函數(shù)、常量等成員定義的上面。
- 如果一個(gè)模塊需要暴露的接口改動(dòng)頻繁,__all__ 可以這樣定義,這樣修改一個(gè)暴露的接口只修改一行,方便版本控制的時(shí)候看 diff。最后多出的逗號(hào)在 Python 中是允許的,符合 PEP8 風(fēng)格。
__all__ = [ "foo", "bar", "egg", ]
Part.II 導(dǎo)入模塊的幾種方法
Chap.I 方法
Python 導(dǎo)入模塊一般用到兩種方法:
import model1
from model import xxx
當(dāng)我們向文件導(dǎo)入某個(gè)模塊時(shí),導(dǎo)入的是該模塊中那些名稱不以下劃線(單下劃線_
或者雙下劃線__
)開(kāi)頭的變量、函數(shù)和類。因此,如果我們不想模塊文件中的某個(gè)成員被引入到其它文件中使用,可以在其名稱前添加下劃線。
除此之外,還可以借助模塊提供的 __all__
變量,該變量的值是一個(gè)列表,存儲(chǔ)的是當(dāng)前模塊中一些成員(變量、函數(shù)或者類)的名稱。通過(guò)在模塊文件中設(shè)置 __all__
變量,當(dāng)其它文件以from 模塊名 import *
的形式導(dǎo)入該模塊時(shí),該文件中只能使用 __all__
列表中指定的成員。
也就是說(shuō),當(dāng)使用
from 模塊名 import *
方法導(dǎo)入模塊的時(shí)候,不會(huì)導(dǎo)入下劃線_
函數(shù);另外,如果模塊中有__all__
,則導(dǎo)入的函數(shù)還要受到__all__
的控制;當(dāng)使用import 模塊名
導(dǎo)入函數(shù)時(shí),則不會(huì)受到上面兩個(gè)的限制。
所以,以后在確定某些函數(shù)不想被訪問(wèn)到,就用下劃線_
或者用__all__
,并使用from 模塊名 import *
方法導(dǎo)入模塊;當(dāng)想要使用模塊中的所有函數(shù)時(shí),則使用import 模塊名
來(lái)導(dǎo)入模塊。
Chap.II 實(shí)例
比如現(xiàn)在有個(gè)文件叫b.py
# ------------ b.py 內(nèi)容 ---------------------- __all__ = [ 'b_hello', '_b_hello' ] def b_hello(): print("B_HELLO") def _b_hello(): print("B_private") def b_world(): print("B_private_world")
現(xiàn)在使用from 模塊名 import *
方法導(dǎo)入模塊來(lái)調(diào)用函數(shù):
from b import * b_hello() _b_hello() b_world() # ------------ return --------(當(dāng) b.py 中沒(méi)有有變量 __all__ 時(shí)) B_HELLO Error:xxxxx B_private_world # ------------ return --------(當(dāng) b.py 中有變量 __all__ 時(shí)) B_HELLO B_private Error:xxxxx
使用
__all__
變量,使得原本不能被訪問(wèn)到的_b_hello
可以被訪問(wèn)到;因?yàn)?code>__all__中沒(méi)有包含b_world
,所以使得原本能被訪問(wèn)到的b_world
不能被訪問(wèn)到。
現(xiàn)在使用import 模塊名
方法導(dǎo)入模塊來(lái)調(diào)用函數(shù):
import b b.b_hello() b._b_hello() b.b_world() # ------------ return -------- B_HELLO B_private B_private_world
所以,以后在確定某些函數(shù)不想被訪問(wèn)到,就用下劃線_
或者用__all__
,并使用from 模塊名 import *
方法導(dǎo)入模塊;當(dāng)想要使用模塊中的所有函數(shù)時(shí),則使用import 模塊名
來(lái)導(dǎo)入模塊。
ps:當(dāng)包(含有
__init__.py
文件的文件夾)中含有子模塊時(shí),可以使用.
來(lái)導(dǎo)入。比如import lib.model1 as md
,就是調(diào)用包lib
中的模塊model1
。
補(bǔ)充:python導(dǎo)入自己的模塊
在實(shí)際的編程生活當(dāng)中,我們除了會(huì)去import已經(jīng)存在的包外,當(dāng)然還會(huì)偶爾自定義一些模塊,然后來(lái)導(dǎo)入,,,其實(shí)一般而言,自定義的模塊也就是一系列的腳本,具體的,自己寫(xiě)好了腳本,然后導(dǎo)入,導(dǎo)入的情況分為以下情況:
1.自定義模塊與所需要調(diào)用自定義模塊的文件在同一文件夾下
這時(shí)的調(diào)用就較為簡(jiǎn)單了,直接導(dǎo)入即可
比如說(shuō)我想要在learnpandas中導(dǎo)入m1.py,只需要在learnpandas腳本開(kāi)頭聲明import m1.py即可
2.自定義模塊與所需要調(diào)用自定義模塊的文件不在同一文件夾下
其實(shí)這個(gè)的話,如果不怕麻煩的話可以用1中的方法,把需要導(dǎo)入的文件一個(gè)一個(gè)手動(dòng)拖到當(dāng)前文件夾中,,,當(dāng)然這個(gè)方法時(shí)比較復(fù)雜的,尤其是要導(dǎo)入的文件較多的時(shí)候,,,,
這個(gè)時(shí)候有一個(gè)更聰明的方法
假設(shè)下圖是我們需要導(dǎo)入的文件目錄
在這種情況下,我們?cè)趂older中新建一個(gè)__init__.py文件,此時(shí)的folder不再是一個(gè)普通的文件夾,而是一個(gè)包 package
在這個(gè)時(shí)候,想導(dǎo)入哪一個(gè)文件的話就只需在文件開(kāi)頭import folder.filename即可(記得要先將自定義庫(kù)路徑添加到Python的庫(kù)路徑中)
3.找到本地庫(kù)的路徑,然后將文件拷進(jìn)去即可
4.手動(dòng)給python添加搜索路徑,具體做法是:
在python安裝目錄的\Lib\site-packages文件夾中建立一個(gè).pth文件,內(nèi)容為自己寫(xiě)的庫(kù)絕對(duì)路徑
- - - - - - - -?- - - - - - - -?- -分割線- - - - - -?- - - - - - - -?- - - -?
將自定義庫(kù)的路徑添加到Python的庫(kù)路徑中去,有如下兩種方法:
1. 動(dòng)態(tài)的添加庫(kù)路徑。在程序運(yùn)行過(guò)程中修改sys.path的值,添加自己的庫(kù)路徑
import sys
sys.path.append(r'your_path')?
2. 在Python安裝目錄下的\Lib\site-packages文件夾中建立一個(gè).pth文件,內(nèi)容為自己寫(xiě)的庫(kù)路徑。示例如下
E:\\work\\Python\\http
E:\\work\\Python\\logging
- - - - - - - -?- - - - - - - 分割線 - - - - - -?- - - - - - - -?- - - -?
在這里說(shuō)一句Python的包搜索路徑:
Python會(huì)在以下路徑中搜索它想要尋找的模塊:
1. 程序所在的文件夾
2. 標(biāo)準(zhǔn)庫(kù)的安裝路徑
3. 操作系統(tǒng)環(huán)境變量PYTHONPATH所包含的路徑
總結(jié)?
原文鏈接:https://blog.csdn.net/Gou_Hailong/article/details/125169752
相關(guān)推薦
- 2022-07-16 不同存圖方式下的DFS和BFS實(shí)現(xiàn)
- 2022-06-08 Spring Cloud Alibaba Nacos 客戶端服務(wù)注冊(cè)心跳和健康監(jiān)測(cè)
- 2022-07-16 Electron項(xiàng)目中的NSIS配置項(xiàng)
- 2022-05-26 Flutter自定義彈窗Dialog效果_Android
- 2022-03-14 flutter 列表左右滑動(dòng)帶出按鈕選項(xiàng)
- 2024-02-16 ReentrantLock相較于synchronized的區(qū)別---鎖超時(shí)(源碼理解)
- 2022-06-20 關(guān)于go-micro與其它gRPC框架之間的通信問(wèn)題及解決方法_Golang
- 2022-11-09 Python運(yùn)算符教程之邏輯門詳解_python
- 最近更新
-
- window11 系統(tǒng)安裝 yarn
- 超詳細(xì)win安裝深度學(xué)習(xí)環(huán)境2025年最新版(
- Linux 中運(yùn)行的top命令 怎么退出?
- MySQL 中decimal 的用法? 存儲(chǔ)小
- get 、set 、toString 方法的使
- @Resource和 @Autowired注解
- Java基礎(chǔ)操作-- 運(yùn)算符,流程控制 Flo
- 1. Int 和Integer 的區(qū)別,Jav
- spring @retryable不生效的一種
- Spring Security之認(rèn)證信息的處理
- Spring Security之認(rèn)證過(guò)濾器
- Spring Security概述快速入門
- Spring Security之配置體系
- 【SpringBoot】SpringCache
- Spring Security之基于方法配置權(quán)
- redisson分布式鎖中waittime的設(shè)
- maven:解決release錯(cuò)誤:Artif
- restTemplate使用總結(jié)
- Spring Security之安全異常處理
- MybatisPlus優(yōu)雅實(shí)現(xiàn)加密?
- Spring ioc容器與Bean的生命周期。
- 【探索SpringCloud】服務(wù)發(fā)現(xiàn)-Nac
- Spring Security之基于HttpR
- Redis 底層數(shù)據(jù)結(jié)構(gòu)-簡(jiǎn)單動(dòng)態(tài)字符串(SD
- arthas操作spring被代理目標(biāo)對(duì)象命令
- Spring中的單例模式應(yīng)用詳解
- 聊聊消息隊(duì)列,發(fā)送消息的4種方式
- bootspring第三方資源配置管理
- GIT同步修改后的遠(yuǎn)程分支