大師兄的Python學(xué)習(xí)筆記(三): 模塊和包

大師兄的Python學(xué)習(xí)筆記(二): 面向?qū)ο蠛皖?/a>
大師兄的Python學(xué)習(xí)筆記(四): Python的內(nèi)置函數(shù)

一、模塊(Module)

1. 關(guān)于模塊

1)什么是模塊

  • 模塊就是以.py結(jié)尾的Python文件。
  • 一個(gè)模塊就是一個(gè).py文件。

2)為什么需要模塊

  • 從文件級(jí)別來(lái)組織程序,方便管理。
  • 可以將相關(guān)的代碼放在一起,代碼邏輯感更強(qiáng)。
  • 方便別人和自己重復(fù)利用代碼。
  • 當(dāng)做命名空間使用,避免命名沖突。
<模塊名>.<成員名>
例1:module.var
例2:module.function()

3)如何定義模塊

  • 模塊就是一個(gè)普通文件,所以任何代碼可以直接書(shū)寫(xiě),
  • 模塊能定義函數(shù),類和變量,模塊里也能包含可執(zhí)行的代碼。
2. 使用模塊
  • 使用模塊就是在模塊外調(diào)用模塊的內(nèi)容。
  • 使用模塊需要使用import指令

1)import <模塊名>

  • 導(dǎo)入一個(gè)模塊。
  • 用<模塊名>.<成員名>調(diào)用模塊內(nèi)容。
# moduleA.py - 模塊1
>>>name = 'moduleA'
>>>def funcA():
>>>    print('Here in funcA.')

# moduleB.py - 模塊2
>>>import moduleA # 導(dǎo)入moduleA
>>>print(moduleA.name) # 調(diào)用了moduleA中的變量
'moduleA'
>>>moduleA.funcA()  # 調(diào)用了moduleA中的函數(shù)
'Here in funcA.'

2)import <模塊名1>, <模塊名2>

  • 導(dǎo)入多個(gè)模塊。
  • 用<模塊名>.<成員名>調(diào)用模塊內(nèi)容。
# moduleA.py - 模塊1
>>>name = 'moduleA'
>>>def funcA():
>>>    print('Here in funcA.')

# moduleB.py - 模塊2
>>>name = 'moduleB'
>>>def funcB():
>>>    print('Here in funcB.')

# moduleC.py - 模塊3
>>>import moduleA, moduleB # 導(dǎo)入moduleA和moduleB
>>>print(moduleA.name) # 調(diào)用了moduleA中的變量
'moduleA'
>>>moduleA.funcA()  # 調(diào)用了moduleA中的函數(shù)
'Here in funcA.'
>>>print(moduleB.name) # 調(diào)用了moduleB中的變量
'moduleB'
>>>moduleB.funcB()  # 調(diào)用了moduleB中的函數(shù)
'Here in funcB.'

3)import <模塊名> as <自定義名稱>

  • 導(dǎo)入模塊并自己給它起個(gè)名字。
  • 用<自定義名稱>.<成員名>調(diào)用模塊內(nèi)容。
# moduleA.py - 模塊1
>>>name = 'moduleA'
>>>def funcA():
>>>    print('Here in funcA.')

# moduleB.py - 模塊2
>>>import moduleA as AAA # 導(dǎo)入moduleA并改名叫AAA
>>>print(AAA.name) # 調(diào)用了moduleA中的變量
'moduleA'
>>>AAA.funcA()  # 調(diào)用了moduleA中的函數(shù)
'Here in funcA.'

4)from <模塊名> import <成員名>

  • 導(dǎo)入模塊中某個(gè)成員。
  • 可以直接用成員名訪問(wèn),也可以使用<模塊名>.<成員名>訪問(wèn)。
  • 如果成員名和本地變量名沖突,則使用最后一個(gè)定義的。
# moduleA.py - 模塊1
>>>name = 'moduleA'
>>>def funcA():
>>>    print('Here in funcA.')

# moduleB.py - 模塊2
>>>from moduleA import name,funcA # 導(dǎo)入moduleA中的兩個(gè)成員
>>>print(name) # 調(diào)用了moduleA中的變量
'moduleA'
>>>print(moduleA.name) # 兩種調(diào)用方式都可以
'moduleA'
>>>funcA()  # 調(diào)用了moduleA中的函數(shù)
'Here in funcA.'
>>>moduleA.funcA()  # 兩種調(diào)用方式都可以
'Here in funcA.'

>>>name = 'moduleB' # 新定義一個(gè)重名變量
>>>print(name)
'moduleB' 
>>>from moduleA import name
>>>print(name) # 以后定義的為準(zhǔn)
'moduleA'

5)from <模塊名> import *

  • 導(dǎo)入模塊中的全部成員。
  • 其它的內(nèi)容與4中相同。
# moduleA.py - 模塊1
>>>name = 'moduleA'
>>>def funcA():
>>>    print('Here in funcA.')

# moduleB.py - 模塊2
>>>from moduleA import * # 導(dǎo)入moduleA中的全部成員
>>>print(name) # 調(diào)用了moduleA中的變量
'moduleA'
>>>funcA()
'Here in funcA.'
3. 關(guān)于if __name__ == "__main__": 的使用
  • 在筆記(二)中,曾經(jīng)提到過(guò)__name__是魔法函數(shù),可以獲得類的名稱
  • 如果直接在模塊中使用__name__,則獲得模塊的名稱
>>>print(__name__) # 如果是在本模塊調(diào)用,則返回__main__。
'__main__'

>>>import test
>>>test.__name__ # 如果是導(dǎo)入的模塊,則返回模塊名。
'test'
  • 所以,if __name__ == "__main__"的含義就是在執(zhí)行本文件時(shí)執(zhí)行后面的程序,如果是導(dǎo)入的模塊則跳過(guò)。
  • 建議所有程序的入口都以此代碼為入口。
# moduleA.py - 模塊1
>>>def funcA():
>>>    print('Here in funcA.')
>>>def funcB():
>>>    print('Here in funcB.')
>>>test2()  # 被當(dāng)做模塊導(dǎo)入時(shí)也會(huì)執(zhí)行執(zhí)行
>>>
>>>if __name__ == "__main__": # 只在本程序執(zhí)行
>>>    test1()
Here in funcA.
Here in funcB.

# moduleB.py - 模塊2
>>>import moduleA # 在使用模塊時(shí),test2()直接被執(zhí)行了,但是test1并沒(méi)有
Here in funcB.
4. 模塊的路徑
  • 加載模塊時(shí),系統(tǒng)會(huì)在默認(rèn)路徑中尋找模塊。
  • 默認(rèn)路徑包括:當(dāng)前目錄、Python安裝路徑的lib庫(kù)、環(huán)境變量PYTHONPATH中指定的路徑列表等
  • 可以通過(guò)sys.path查看默認(rèn)路徑列表
>>>import sys #導(dǎo)入sys包
>>>print(sys.path)
['D:\\PyCharm Community Edition 2019.1\\helpers\\pydev', 'D:\\PyCharm Community Edition 2019.1\\helpers\\third_party\\thriftpy', 'D:\\PyCharm Community Edition 2019.1\\helpers\\pydev', 'D:\\Python3.7\\python37.zip', 'D:\\Python3.7\\DLLs', 'D:\\Python3.7\\lib', 'D:\\Python3.7', 'C:\\Users\\xiaor\\PycharmProjects\\test\\venv', 'C:\\Users\\xiaor\\PycharmProjects\\test\\venv\\lib\\site-packages', 'C:\\Users\\xiaor\\PycharmProjects\\test\\venv\\lib\\site-packages\\setuptools-39.1.0-py3.7.egg', 'C:\\Users\\xiaor\\PycharmProjects\\test\\venv\\lib\\site-packages\\pip-10.0.1-py3.7.egg', 'C:\\Users\\xiaor\\PycharmProjects\\test', 'C:/Users/xiaor/PycharmProjects/test']
  • 可以通過(guò)sys.path.append添加搜索路徑
>>>import sys
>>>sys.append('d:\\test') # 添加新的搜索路徑
>>>print(sys.path[-1])  # 獲得list中最后一個(gè)地址
'd:\\test'
  • 模塊的加載順序:內(nèi)存中已經(jīng)加載好的模塊 >> python內(nèi)置模塊 >> sys.path路徑
5. .pyc和.pyo文件
  • Python解釋器會(huì)在模塊目錄下創(chuàng)建__pycache__文件夾,并在文件夾內(nèi)創(chuàng)建對(duì)應(yīng)的.pyc文件
  • .pyc文件是二進(jìn)制文件,目的是加快解釋速度且可以隱藏源代碼。
  • Python解釋器在解釋.py文件時(shí),會(huì)優(yōu)先查看是否有對(duì)應(yīng)的最新的.pyc文件,有的話則直接加載.pyc文件。
  • 最新的.pyc文件會(huì)被優(yōu)先import,并可以被單獨(dú)當(dāng)做模塊使用。
  • .pyo文件與.pyc文件作用一致,是優(yōu)化后的版本。

二、包(Package)

1. 什么是包
  • 包是用來(lái)組織管理代碼的方式。
  • 包里面存放的是模塊。
  • 可以將包理解為存放模塊的文件夾。
  • 包含一個(gè)文件名為__init__.py的文件
2. 包的結(jié)構(gòu)

/包
/------/------ __init__.py文件
/------/------ 模塊1
/------/------ 模塊2
/------/------ 子包
/------/------/------ __init__.py文件
/------/------/------ 子模塊1
/------/------/------ 子模塊2

3.關(guān)于__init__.py
  • __init__.py是一個(gè)Python文件。
  • 如果一個(gè)文件夾中包含__init__.py,Python就會(huì)把這個(gè)文件夾當(dāng)做一個(gè)包。
  • 訪問(wèn)包會(huì)默認(rèn)訪問(wèn)__init__.py文件。
  • 可以在__init__.py中添加導(dǎo)入包時(shí)默認(rèn)導(dǎo)入的模塊。
/mypackage
/------/------ __init__.py
/------/------ moduleA

#__init__.py
>>>import mypackage.moduleA # 默認(rèn)導(dǎo)入moduleA,這里需要用全地址。

# 控制臺(tái)
>>>import mypackage
>>>if __name__ == "__main__": 
>>>    print(mypackage.moduleA) # 可以直接從包中訪問(wèn)
<module 'mypackage.moduleA' from 'D:\\mypackage\\moduleA.py'>
  • 在導(dǎo)入包時(shí),可以使用__init__.py中的內(nèi)容。
/mypackage
/------/------ __init__.py

# __init__.py文件
>>>def showPosition(): # 在__init__.py中創(chuàng)建方法
>>>    print('here in __init__.py')

# 控制臺(tái)
>>>import mypackage 
>>>mypackage.showPosition()  # 可以直接調(diào)用__init__.py中的方法
'here in __init__.py'
  • 可以在__init__.py中使用__all__定義from <包> import *時(shí)導(dǎo)入的模塊包含哪些。
/mypackage
/------/------ __init__.py
/------/------ moduleA
/------/------ moduleB

# __init__.py文件
>>> __all__ = ['moduleA'] # 指定*只包含moduleA

# 控制臺(tái)
>>>if __name__ == "__main__": 
>>>    from mypackage import *
>>>    print(moduleA) # 成功導(dǎo)入
<module 'mypackage.moduleA' from 'mypackage\\__init__.py'>
>>>    print(moduleB) # 導(dǎo)入失敗
NameError: name 'moduleB' is not defined
4.包的使用

與模塊相同,導(dǎo)入包需要使用import指令。
1)import <包名>

  • 導(dǎo)入一個(gè)包。
  • 可以使用__init__.py中的內(nèi)容
  • 用<包名>.<模塊名>調(diào)用具體的模塊。
/mypackage
/------/------ __init__.py
/------/------ moduleA

# __init__
>>>import mypackage.moduleA

# moduleA
>>>def sayHi():
>>>    print('here in moduleA!')

# 控制臺(tái)
>>>import mypackage # 導(dǎo)入包
>>>if __name__ == "__main__": 
>>>    mypackage.moduleA.sayHi() # 調(diào)用包中模塊的函數(shù)
'here in moduleA!'

2)import <包名>.<模塊名>

  • 導(dǎo)入包中的某個(gè)模塊。
/mypackage
/------/------ __init__.py
/------/------ moduleA

# moduleA
>>>def sayHi():
>>>    print('here in moduleA!')

# 控制臺(tái)
>>>import mypackage.moduleA # 直接導(dǎo)入包中的模塊
>>>if __name__ == "__main__": 
>>>    moduleA.sayHi() # 調(diào)用模塊的函數(shù)
'here in moduleA!'

3)import <包名> as <自定義名>

  • 自定義包的名稱。
  • 注意,這種方法實(shí)際調(diào)用的是__init__.py中的內(nèi)容。
/mypackage
/------/------ __init__.py
/------/------ moduleA

# __init__
>>># import mypackage.moduleA 也可以
>>>__all__ = ['moduleA']

# moduleA
>>>def sayHi():
>>>    print('here in moduleA!')

# 控制臺(tái)
>>>import mypackage as mpkg # 導(dǎo)入包并自定義名稱
>>>if __name__ == "__main__": 
>>>    mpkg.moduleA.sayHi() # 調(diào)用包中模塊的函數(shù)
'here in moduleA!'

4)from <包名> import <模塊名>

  • 導(dǎo)入包中的模塊。
/mypackage
/------/------ __init__.py
/------/------ moduleA
/------/------ moduleB

>>>from mypackage import moduleA,moduleB # 導(dǎo)入兩個(gè)模塊
>>>if __name__ == "__main__": 
>>>    print(moduleA)
<module 'mypackage.moduleA' from 'D:\\mypackage\\moduleA.py'>

5)from <包名> import *

  • 導(dǎo)入__init__.py中的所有模塊。
/mypackage
/------/------ __init__.py
/------/------ moduleA
/------/------ moduleB
/------/------ moduleC

# __init__.py
>>>__all__ = ['moduleA','moduleB']

# 控制臺(tái)
>>>from mypackage import * # 導(dǎo)入所有__init__.py中的模塊
>>>if __name__ == "__main__": 
>>>    print(moduleA)
<module 'mypackage.moduleA' from 'D:\\mypackage\\moduleA.py'>
>>>    print(moduleC) # 未包含在__init__.py中
NameError: name 'moduleC' is not defined

6)from <包名>.<模塊名> import *

  • 導(dǎo)入包的某個(gè)模塊中的所有內(nèi)容。
/mypackage
/------/------ __init__.py
/------/------ moduleA

# __init__.py
>>>__all__ = ['moduleA']

# moduleA
>>>def sayHi():
>>>    print('here in moduleA')

# 控制臺(tái)
>>>from mypackage.moduleA import *
>>>if __name__ == "__main__": 
>>>    sayHi() # 直接使用模塊的函數(shù)名
'here in moduleA'

參考資料



本文作者:大師兄(superkmi)


夢(mèng)幻微武俠
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容