一、什么是包?

包是模塊的一種形式,包的本質就是一個含有.py的文件的文件夾。

二、為什么要有包?

模塊的第一個版本只有10個功能,但是未來在擴展版本的時候,模塊名和用法應該最好不要去修改,但是這只是對使用者友好,而由於版本擴展,文件越來越大,模塊設計者對模塊的管理、維護會越來越復雜,因此我們可以使用包來擴展模塊的功能。

三、如何用包?

3.1 模塊和包

導入模塊發生的三件事:

  1. 創建一個包的名稱空間
  2. 執行py文件,將執行過程中產生的名字存放於名稱空間中。
  3. 在當前執行文件中拿到一個名字aaa,aaa是指向包的名稱空間的

導入包發生的三件事:

  1. 創建一個包的名稱空間
  2. 由於包是一個文件夾,無法執行包,因此執行包下的.py文件,將執行過程中產生的名字存放於包名稱空間中(即包名稱空間中存放的名字都是來自於.py)
  3. 在當前執行文件中拿到一個名字aaa,aaa是指向包的名稱空間的

導入包就是在導入包下的.py,並且可以使用以下兩種方式導入:

  1. import ...
  2. from ... import...

3.2 擴展模塊功能

65包-目錄結構.jpg?x-oss-process=style/watermark

如下我們如果需要擴展aaa.py模塊,需要建立一個aaa的目錄文件,並且刪除aaa.py文件,將aaa.py修改成m1.py和m2.py兩個文件,讓模塊的功能使用方法不改變。

# aaa.py

def func1():
    pass

def func2():
    pass

def func3():
    pass

def func4():
    pass

def func5():
    pass

def func6():
    pass
# m1.py

def func1():
    pass

def func2():
    pass

def func3():
    pass
# m2.py

def func4():
    pass

def func5():
    pass

def func6():
    pass
# run.py

import aaa

aaa.func1()
aaa.func2()
aaa.func3()
aaa.func4()
aaa.func5()
aaa.func6()

3.3 修改__init__.py文件

# aaa/.py

func1 = 111
func2 = 222
func3 = 333
func4 = 444
func5 = 555
func6 = 666

由於在__init__.py中定義了func1,因此我們可以在run.py文件中導入func1,但是這個func1並不是我們想要的func1,因此需要修改__init__.py文件,又由於執行文件run.py的環境變量不為aaa,因此直接使用import導入m1會報錯,因此使用from導入。

# aaa/.py

from aaa.m1 import func1
from aaa.m2 import func2
# run.py

import aaa


print(aaa.func1())
print(aaa.func2())

3.4 導入包內包

aaa.bbb指向aaa內部的文件夾bbb包,如果我們需要導入bbb這個包。

# bbb/.py

from aaa import bbb
# run.py

import aaa


print(aaa.bbb)

3.5 導入包內包的模塊

如果bbb包內部有m3.py,我們需要從run.py導入m3模塊。

# bbb/.py

from aaa.bbb import m3
# run.py

import aaa


aaa.bbb.m3

3.6 絕對導入和相對導入

絕對導入:

# aaa/.py

from aaa.m1 import func1
from aaa.m2 import func2

相對導入:

  • .代表當前被導入文件所在的文件夾
  • ..代表當前被導入文件所在的文件夾的上一級
  • ...代表當前被導入文件所在的文件夾的上一級的上一級

from .m1 import func1
from .m2 import func2

四、注意事項

  1. 包內所有的文件都是被導入使用的,而不是被直接運行的
  2. 包內部模塊之間的導入可以使用絕對導入(以包的根目錄為基准)與相對導入(以當前被導入的模塊所在的目錄為基准),推薦使用相對導入
  3. 當文件是執行文件時,無法在該文件內用相對導入的語法,只有在文件時被當作模塊導入時,該文件內才能使用相對導入的語法
  4. 凡是在導入時帶點的,點的左邊都必須是一個包,import aaa.bbb.m3.f3錯誤

65包-頭大.jpg?x-oss-process=style/watermark

五、練習

65包-目錄結構.jpg?x-oss-process=style/watermark

假設我們有如上的目錄結構,文件內代碼如下:

# m1.py 

def f1():
    print('from f1')
# m2.py 

def f2():
    print('from f2')
# m3.py 

def f3():
    print('from f3')

1.如果我們需要在run.py中實現以下邏輯代碼,因此得在__init__.py文件中如此做:

# run.py

import aaa

aaa.f1()
aaa.f2()
aaa.f3()

print(aaa.bbb)
# aaa/__init__.py

from .m1 import f1
from .m2 import f2
from .bbb.m3 import f3

from . import bbb

2.如果我們需要在run.py中實現以下邏輯,__init__.py什么都不需要做:

# run.py

from aaa.bbb.m3 import f3


f3()


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM