python包相關(guān)知識點(diǎn)之包的導(dǎo)入、相對路徑以及絕對路徑
一、包
在我們的項(xiàng)目中,可能會有太多的模塊
但是我們不能把所有的模塊這樣放在這里,這樣項(xiàng)目會亂七八糟。
我們可以將所有相同類型的模塊放在一個(gè)文件夾中,這個(gè)文件夾就叫做包
包就是文件夾,他用于存放文件也就是模塊。包中也可以存放包
包就是一個(gè)包含了__init__.py文件的文件夾。
包只是模塊的一種形式而已,包即模塊。
包的結(jié)構(gòu):
包
|----__init__.py 包的標(biāo)志文件
|----模塊一
|----模塊二
|----子包(文件夾)
|----|----__init__.py
|----|----子模塊一
|----|----子模塊二
二、包的導(dǎo)入
1.關(guān)于包相關(guān)的導(dǎo)入語句也分為import和from ... import ...兩種,但是無論哪種,無論在什么位置,在導(dǎo)入時(shí)都必須遵循一個(gè)原則:凡是在導(dǎo)入時(shí)帶點(diǎn)的,點(diǎn)的左邊都必須是一個(gè)包,否則非法??梢詭в幸贿B串的點(diǎn),如demo0demo02.demo03,但都必須遵循這個(gè)原則。
2.對于導(dǎo)入后,在使用時(shí)就沒有這種限制了,點(diǎn)的左邊可以是包,模塊,函數(shù),類(它們都可以用點(diǎn)的方式調(diào)用自己的屬性)。
3.對比import demo和from demo import name的應(yīng)用場景:
如果我們想直接使用name那必須使用后者。
1.import 導(dǎo)入
在demo01_test02.py 中 導(dǎo)入 demo01_test01.py
demo01_test01.py 源碼:
def say(): print('demo01_test01_hello') name = '趙四'
demo01_test02.py 源碼:
import base.demo01.demo01_test01 base.demo01.demo01_test01.say() # 調(diào)用test01中的say方法 輸出 demo01_test01_hello import sys print(sys.path) #['D:\\pycharm工作空間\\day12\\base\\demo01', 'D:\\pycharm工作空間\\day12', 'C:\\Users\\Administrator\\AppData\\Local\\Programs\\Python\\Python36\\python36.zip', 'C:\\Users\\Administrator\\AppData\\Local\\Programs\\Python\\Python36\\DLLs', 'C:\\Users\\Administrator\\AppData\\Local\\Programs\\Python\\Python36\\lib', 'C:\\Users\\Administrator\\AppData\\Local\\Programs\\Python\\Python36', 'C:\\Users\\Administrator\\AppData\\Local\\Programs\\Python\\Python36\\lib\\site-packages', 'C:\\Users\\Administrator\\AppData\\Local\\Programs\\Python\\Python36\\lib\\site-packages\\win32', 'C:\\Users\\Administrator\\AppData\\Local\\Programs\\Python\\Python36\\lib\\site-packages\\win32\\lib', 'C:\\Users\\Administrator\\AppData\\Local\\Programs\\Python\\Python36\\lib\\site-packages\\Pythonwin', 'C:\\Program Files\\JetBrains\\PyCharm 2018.3.2\\helpers\\pycharm_matplotlib_backend']
2.from...import...導(dǎo)入
from 包名.模塊名... import 變量名
使用方式: 例如 變量名() 或者print(變量名)
demo01_test02.py 源碼:
from base.demo01.demo01_test01 import say say() # demo01_test01_hello
from 包名.模塊名... import 變量名1,變量名2,...
使用方式: 例如 變量名1() 或者print(變量名2)
demo01_test02.py 源碼:
from base.demo01.demo01_test01 import say,name say() print(name) # 調(diào)用test01中的name變量
from 包名 import 模塊名
使用方式:模塊名.變量名() 或者 print(模塊名.變量名)
demo01_test02.py 源碼:
from base.demo01 import demo01_test01 demo01_test01.say() # demo01_test01_hello
from 包名 import 模塊名,模塊名1...
使用方式:模塊名.變量名() 或者 print(模塊名1.變量名)
在demo01_test02.py中調(diào)用demo02_test01.py, demo02_test02.py 源碼
demo02_test01.py 源碼:
def say21(): print('demo02_test01_hello')
demo02_test02.py 源碼:
def say22(): print('demo02_test02_hello')
demo01_test02.py 源碼:
from base.demo02 import demo02_test01,demo02_test02 demo02_test01.say21() # demo02_test01_hello demo02_test02.say22() # demo02_test02_hello
需要注意的是from后import導(dǎo)入的模塊,必須是明確的一個(gè)不能帶點(diǎn),否則會有語法錯(cuò)誤,如:from a import b.c是錯(cuò)誤語法
from base.demo02 import demo02_test02.say # 報(bào)錯(cuò) SyntaxError: invalid syntax
3.__init__.py文件
不管是哪種方式,只要是第一次導(dǎo)入包或者是包的任何其他部分,都會依次執(zhí)行包下的__init__.py文件(我們可以在每個(gè)包的文件內(nèi)都打印一行內(nèi)容來驗(yàn)證一下),這個(gè)文件可以為空,但是也可以存放一些初始化包的代碼。
demo1下的__init__.py文件源碼:
print('啦啦啦')
demo01_test02.py 源碼:
from base.demo01 import demo01_test01 demo01_test01.say() # 啦啦啦 __init__.py中的代碼執(zhí)行結(jié)果 # demo01_test01_hello
4.from 包.模塊 import *
此處是想從包demo02中導(dǎo)入所有,實(shí)際上該語句只會導(dǎo)入包demo02下__init__.py文件中定義的名字,我們可以在這個(gè)文件中定義__all___:
demo02下__init__.py文件的源碼:
print('嗚嗚嗚') name = '王大夫'
demo01_test02.py 源碼:
from base.demo02 import * print(name) # 王大夫 demo02_test01.say() # 報(bào)錯(cuò) 無法調(diào)用 # 輸出: 嗚嗚嗚 # NameError: name 'demo02_test01' is not defined
在demo02下的__init__.py文件中加入以下源碼:
print('嗚嗚嗚') name = '王大夫' __all__ = ['demo02_test01','demo02_test02']
再調(diào)用:
from base.demo02 import * demo02_test01.say21() # 成功調(diào)用 print(name) # 報(bào)錯(cuò) 變量name沒有定義 # 嗚嗚嗚 # demo02_test01_hello
三、包的相對和絕對導(dǎo)入
我們的最頂級包base是寫給別人用的,然后在base包內(nèi)部也會有彼此之間互相導(dǎo)入的需求,這時(shí)候就有絕對導(dǎo)入和相對導(dǎo)入兩種方式:
絕對導(dǎo)入:以base作為起始
相對導(dǎo)入:用.或者..的方式最為起始(只能在一個(gè)包中使用,不能用于不同目錄內(nèi))
1. 絕對導(dǎo)入
在demo01中的demo01_test02.py中調(diào)用demo02中的模塊
from base.demo01 import demo01_test01 demo01_test01.say()
在 base目錄下的py文件中調(diào)用demo01_test02.py
from base.demo01 import demo01_test02 demo01_test02.demo01_test01.say()
2.相對導(dǎo)入
在demo01中的demo01_test02.py中調(diào)用demo02中的模塊
from ..demo02.demo02_test01 import say21 say21()
在 base目錄下的py文件中調(diào)用demo01_test02.py
from base.demo01 import demo01_test02 demo01_test02.say21() import sys print(sys.path) ''' 啦啦啦 嗚嗚嗚 demo02_test01_hello demo02_test01_hello ['D:\\pycharm工作空間\\day12\\base', 'D:\\pycharm工作空間\\day12', 'C:\\Users\\Administrator\\AppData\\Local\\Programs\\Python\\Python36\\python36.zip', 'C:\\Users\\Administrator\\AppData\\Local\\Programs\\Python\\Python36\\DLLs', 'C:\\Users\\Administrator\\AppData\\Local\\Programs\\Python\\Python36\\lib', 'C:\\Users\\Administrator\\AppData\\Local\\Programs\\Python\\Python36', 'C:\\Users\\Administrator\\AppData\\Local\\Programs\\Python\\Python36\\lib\\site-packages', 'C:\\Users\\Administrator\\AppData\\Local\\Programs\\Python\\Python36\\lib\\site-packages\\win32', 'C:\\Users\\Administrator\\AppData\\Local\\Programs\\Python\\Python36\\lib\\site-packages\\win32\\lib', 'C:\\Users\\Administrator\\AppData\\Local\\Programs\\Python\\Python36\\lib\\site-packages\\Pythonwin', 'C:\\Program Files\\JetBrains\\PyCharm 2018.3.2\\helpers\\pycharm_matplotlib_backend'] '''
相對路徑運(yùn)行注意事項(xiàng):
在沒有明確指定包結(jié)構(gòu)的情況下,Python 是根據(jù) __name__ 來決定一個(gè)模塊在包中的結(jié)構(gòu)的,如果是 __main__ 則它本身是頂層模塊,沒有包結(jié)構(gòu),如果是base.demo01.demo02 結(jié)構(gòu),那么頂層模塊是 base。
如果是相對導(dǎo)入,一個(gè)模塊必須有包結(jié)構(gòu)且只能導(dǎo)入它的頂層模塊內(nèi)部的模塊
如果一個(gè)模塊被直接運(yùn)行,則它自己為頂層模塊,不存在層次結(jié)構(gòu),所以找不到其他的相對路徑。
四、import 導(dǎo)入自定義包的子模塊
特別需要注意的是:可以用import導(dǎo)入內(nèi)置或者第三方模塊(已經(jīng)在sys.path中),但是要絕對避免使用import來導(dǎo)入自定義包的子模塊(沒有在sys.path中),應(yīng)該使用from... import ...的絕對或者相對導(dǎo)入。
demo03中的test01源碼:
def test(): print('這是一個(gè)測試方法')
直接運(yùn)行demo03_test02模塊
import test01 test01.test() import sys print(sys.path) '''這是一個(gè)測試方法 ['D:\\pycharm工作空間\\day12\\base\\demo03', 'D:\\pycharm工作空間\\day12', 'D:\\pycharm工作空間\\day12\\base\\demo03', 'C:\\Users\\Administrator\\AppData\\Local\\Programs\\Python\\Python36\\python36.zip', 'C:\\Users\\Administrator\\AppData\\Local\\Programs\\Python\\Python36\\DLLs', 'C:\\Users\\Administrator\\AppData\\Local\\Programs\\Python\\Python36\\lib', 'C:\\Users\\Administrator\\AppData\\Local\\Programs\\Python\\Python36', 'C:\\Users\\Administrator\\AppData\\Local\\Programs\\Python\\Python36\\lib\\site-packages', 'C:\\Users\\Administrator\\AppData\\Local\\Programs\\Python\\Python36\\lib\\site-packages\\win32', 'C:\\Users\\Administrator\\AppData\\Local\\Programs\\Python\\Python36\\lib\\site-packages\\win32\\lib', 'C:\\Users\\Administrator\\AppData\\Local\\Programs\\Python\\Python36\\lib\\site-packages\\Pythonwin', 'C:\\Program Files\\JetBrains\\PyCharm 2018.3.2\\helpers\\pycharm_matplotlib_backend'] '''
不會報(bào)錯(cuò)因?yàn)閟ys.path中已經(jīng)添加了day05-包/demo03路徑。Import會從sys.path中依次搜索路徑。
在base目錄下導(dǎo)入demo03_test02.py進(jìn)行使用
from base.demo03 import test02 # 報(bào)錯(cuò) ModuleNotFoundError: No module named 'test01'
因?yàn)榇藭r(shí)的sys.path中只有demo01-包.py的路徑 .../day05-包,import demo03_test01 只能從/day05-包下查找 demo03_test01模塊。找不到因此報(bào)錯(cuò)。
解決import 導(dǎo)入包時(shí)的報(bào)錯(cuò)問題
我們可以在sys.path中添加import搜索的路徑。
import sys,os path = os.path.abspath(__file__) print(path) BASE_DIR = os.path.dirname(os.path.abspath(__file__)) print(BASE_DIR) sys.path.append(BASE_DIR) print(sys.path) import base.demo03.test01 base.demo03.test01.test() # 這是一個(gè)測試方法
五、包的單獨(dú)導(dǎo)入
單獨(dú)導(dǎo)入包名稱時(shí)不會導(dǎo)入包中所有包含的所有子模塊
import base.demo03 base.demo03.test01.test() # 報(bào)錯(cuò) AttributeError: module 'base.demo03' has no attribute 'test01'
解決辦法:需要從__init__.py中進(jìn)行初始化操作
進(jìn)行上訴操作后:
六、包的安裝和發(fā)布
1、在包的同級目錄創(chuàng)建 setup.py
from distutils.core import setup setup(name='bag', version='1.0,3', description='描述:這是我的第一個(gè)包', author='zxb', author_email='505555162@qq.com', py_modules=['test1', 'test2'], )
2.在命令行 運(yùn)行 python setup.py build (可以不執(zhí)行 )
構(gòu)建模塊
4.生成發(fā)布的壓縮包 運(yùn)行 python setup.py sdist
5、安裝包
導(dǎo)入自己的包進(jìn)行測試
測試成功??!
包的卸載: 直接找到對應(yīng)的位置刪除即可。
總結(jié)
到此這篇關(guān)于python包相關(guān)知識點(diǎn)之包的導(dǎo)入、相對路徑以及絕對路徑的文章就介紹到這了,更多相關(guān)python包的導(dǎo)入、相對及絕對路徑內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Python+Tableau廣東省人口普查可視化的實(shí)現(xiàn)
本文將結(jié)合實(shí)例代碼,介紹Python+Tableau廣東省人口普查可視化,第七次人口普查數(shù)據(jù)分析,繪制歷次人口普查人口數(shù)量變化圖,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2021-06-06tensorflow中tf.slice和tf.gather切片函數(shù)的使用
今天小編就為大家分享一篇tensorflow中tf.slice和tf.gather切片函數(shù)的使用,具有很好的參考價(jià)值,希望對大家有所幫助。一起跟隨小編過來看看吧2020-01-01pytorch中Transformer進(jìn)行中英文翻譯訓(xùn)練的實(shí)現(xiàn)
本文主要介紹了pytorch中Transformer進(jìn)行中英文翻譯訓(xùn)練的實(shí)現(xiàn),詳細(xì)闡述了使用PyTorch實(shí)現(xiàn)Transformer模型的代碼實(shí)現(xiàn)和訓(xùn)練過程,具有一定參考價(jià)值,感興趣的可以了解一下2023-08-08Python字符串的encode與decode研究心得亂碼問題解決方法
為什么Python使用過程中會出現(xiàn)各式各樣的亂碼問題,明明是中文字符卻顯示成“\xe4\xb8\xad\xe6\x96\x87”的形式?2009-03-03一波神奇的Python語句、函數(shù)與方法的使用技巧總結(jié)
這篇文章主要介紹了一波神奇的Python函數(shù)與方法的使用技巧總結(jié),包括裝飾器和with語句等的不常見用法,需要的朋友可以參考下2015-12-12淺述python中argsort()函數(shù)的實(shí)例用法
本篇文章主要介紹了淺述python中argsort()函數(shù)的實(shí)例用法,詳細(xì)的介紹了argsort()函數(shù)的用法,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下。2017-03-03用python 批量更改圖像尺寸到統(tǒng)一大小的方法
下面小編就為大家分享一篇用python 批量更改圖像尺寸到統(tǒng)一大小的方法,具有很好的參考價(jià)值,希望對大家有所幫助。一起跟隨小編過來看看吧2018-03-03