python模块大全使用说明_python模块详解
使用python時(shí),常常會(huì)涉及到庫(kù)的調(diào)用,這就需要掌握模塊的基本知識(shí)。本文分為如下幾個(gè)部分
概念說(shuō)明
模塊的簡(jiǎn)單調(diào)用
包的導(dǎo)入
特殊的__init__.py文件
導(dǎo)入模塊的搜索路徑
__all__
絕對(duì)引用與相對(duì)引用
import運(yùn)行本質(zhì)
if __name__ == '__main__'
概念說(shuō)明
這里厘清python中模塊、庫(kù)、包之間的概念差異
模塊(module)其實(shí)就是py文件,里面定義了一些函數(shù)、類(lèi)、變量等
包(package)是多個(gè)模塊的聚合體形成的文件夾,里面可以是多個(gè)py文件,也可以嵌套文件夾
庫(kù)是參考其他編程語(yǔ)言的說(shuō)法,是指完成一定功能的代碼集合,在python中的形式就是模塊和包
模塊的簡(jiǎn)單調(diào)用
比如我們有一個(gè)trymodule的文件夾,里面有一個(gè)first.py文件,文件中的內(nèi)容如下
a = 1
def myfun(s):
print(s + 1)
復(fù)制代碼
在trymodule的文件夾下打開(kāi)命令行窗口(按住shift單擊鼠標(biāo)右鍵,選擇“在此處打開(kāi)命令窗口”),輸入python進(jìn)入命令行交互模式
>>> import first
>>> a
Traceback (most recent call last):
File "", line 1, in
NameError: name 'a' is not defined
>>> first.a
1
>>> first.myfun(2)
3
復(fù)制代碼
所以說(shuō)first.py文件就是一個(gè)模塊,可以用import導(dǎo)入,里面變量都要用first.前綴來(lái)引用,如果想不使用這個(gè)前綴可以這樣
>>>from first import a
>>>a
1
復(fù)制代碼
其他用法如下
# 重命名
>>>from first import myfun as addone
>>>addone(4)
5
# 導(dǎo)入模塊中全部變量
>>>from first import *
>>>myfun(2)
3
# 一次導(dǎo)入多個(gè)變量
>>>from first import a, myfun
>>>a
1
復(fù)制代碼
包的導(dǎo)入
在trymodule文件夾中新建folder1文件夾,我們想讓folder1文件夾成為一個(gè)包。文件夾里新建abcd.py文件,文件中內(nèi)容如下
b = 2
class Myclass:
def __init__(self, name, age):
self.name = name
self.age = age
def get_info(self):
print('my name is {name} and age is {age}'.format(name = self.name, age = self.age))
復(fù)制代碼
此時(shí)在folder1文件夾中新建一個(gè)__init__.py文件,否則程序會(huì)將這個(gè)文件夾當(dāng)成普通文件夾來(lái)處理而不是一個(gè)包。這個(gè)__init__.py文件中可以什么都不填。
此時(shí)文件結(jié)構(gòu)如下
trymodule
│ first.py
├───folder1
│ │ abcd.py
│ │ __init__.py
復(fù)制代碼
我們還是在trymodule文件夾下打開(kāi)命令行,進(jìn)入python交互模式
我們來(lái)看一下下面幾種導(dǎo)入方式
>>> import folder1
>>> folder1.abcd.b
Traceback (most recent call last):
File "", line 1, in
AttributeError: module 'folder1' has no attribute 'abcd'
>>> from folder1 import abcd
>>> bob = abcd.Myclass(name = 'Bob', age = 20)
>>> bob.name
'Bob'
>>> bob.get_info()
my name is Bob and age is 20
>>> from folder1.abcd import b
>>> b
2
>>> import folder1.abcd
>>> abcd.b
Traceback (most recent call last):
File "", line 1, in
NameError: name 'abcd' is not defined
>>> folder1.abcd.b
2
>>> import folder1.abcd as aa
>>> aa.b
2
復(fù)制代碼
注意:
只是導(dǎo)入包不能隨便使用其中的模塊,要導(dǎo)入到具體模塊或者變量的層次
文件夾與文件之間可以用.也可以用from import格式,而文件與里面的變量之間只能用from import格式,即不能import folder1.abcd.b
特殊的__init__.py文件
__init__.py文件其實(shí)是一個(gè)特殊的文件,它相當(dāng)于名為folder1模塊,即如果使用import folder1則可以調(diào)用在__init__.py文件文件中定義的變量。
將__init__.py文件編寫(xiě)如下
from folder1.abcd import b
c = 3
復(fù)制代碼
在trymodule文件夾下打開(kāi)命令行,進(jìn)入python交互模式
>>> import folder1
>>> folder1.c
3
>>> folder1.b
2
>>> from folder1 import b
>>> b
2
復(fù)制代碼
對(duì)比之前的from folder1.abcd import b,使用__init__.py文件可以將常用的一些變量導(dǎo)入以方便調(diào)用。
另外需要注意兩點(diǎn)
__init__.py文件編寫(xiě)時(shí),如果要導(dǎo)入其他模塊中的變量,即使__init__.py文件和abcd.py文件在同一個(gè)文件夾下,也不能from abcd import b,要從abcd文件從哪里來(lái)的開(kāi)始寫(xiě),即從包的名稱(chēng)開(kāi)始。
folder1文件夾里的嵌套文件夾內(nèi)不需要新建__init__.py文件即可像模塊一樣調(diào)用,但是一般還是要新建這個(gè)文件,可以方便地導(dǎo)入常用變量。
導(dǎo)入模塊的搜索路徑
用import hello時(shí),python會(huì)搜尋hello.py文件,搜索順序如下
首先搜尋內(nèi)置模塊是否有hello(所以我們定義的模塊名不要和內(nèi)置模塊相同)
如果內(nèi)置模塊沒(méi)有,則看下面這些目錄里有沒(méi)有
>>> import sys
>>> sys.path
['', 'C:\\Program Files\\Anaconda3\\python35.zip', 'C:\\Program Files\\Anaconda3\\DLLs', 'C:\\Program Files\\Anaconda3\\lib', 'C:\\Program Files\\Anaconda3', 'C:\\Program Files\\Anaconda3\\lib\\site-packages', 'C:\\Program Files\\Anaconda3\\lib\\site-packages\\Sphinx-1.4.6-py3.5.egg', 'C:\\Program Files\\Anaconda3\\lib\\site-packages\\snownlp-0.12.3-py3.5.egg', 'C:\\Program Files\\Anaconda3\\lib\\site-packages\\win32', 'C:\\Program Files\\Anaconda3\\lib\\site-packages\\win32\\lib', 'C:\\Program Files\\Anaconda3\\lib\\site-packages\\Pythonwin', 'C:\\Program Files\\Anaconda3\\lib\\site-packages\\setuptools-27.2.0-py3.5.egg']
復(fù)制代碼
其中第一個(gè)''表示當(dāng)前的工作路徑,我們可以看出安裝的第三方包所在路徑('C:\\Program Files\\Anaconda3\\lib\\site-packages')也在這個(gè)列表之中,所以無(wú)論工作路徑在哪里,都能搜尋到這些包。
如果想添加搜索路徑,可以參考這篇文章
__all__
首先要明確,import *的方式無(wú)法導(dǎo)入以下劃線開(kāi)頭的變量名
__init__.py文件內(nèi)容更改如下
from folder1.abcd import b
c = 3
_e = 4
復(fù)制代碼
python交互模式下
>>> from folder1 import *
>>> c
3
>>> _e
Traceback (most recent call last):
File "", line 1, in
NameError: name '_e' is not defined
復(fù)制代碼
而如果指定導(dǎo)入是可以的
>>>from folder1 import c
>>>c
3
>>>from folder1 import _e
>>>_e
4
復(fù)制代碼
如果定義了__all__,則import *就可以導(dǎo)入下劃線開(kāi)頭的變量
__init__.py文件內(nèi)容更改如下
from folder1.abcd import b
__all__ = ['c', '_e']
c = b + 1
_e = 4
復(fù)制代碼
python交互模式下
>>> from folder1 import *
>>> b
Traceback (most recent call last):
File "", line 1, in
NameError: name 'b' is not defined
>>> c
3
>>> _e
4
復(fù)制代碼
可見(jiàn)import *只會(huì)導(dǎo)入__all__中指定的變量,無(wú)論是否以下劃線開(kāi)頭。這樣限制可以防止import *命令導(dǎo)入太多變量污染命名空間,過(guò)濾掉一些中間變量如b
絕對(duì)引用與相對(duì)引用
python中的import分為絕對(duì)引用和相對(duì)引用兩種。它們之間的差異在于,引用模塊時(shí) 定位被引用模塊位置 的方式不同
絕對(duì)引用是明確指定最高級(jí)文件(夾),文件之間用.連接,依次下來(lái)達(dá)到待引用模塊。我們上面的所有用法都屬于絕對(duì)引用。
而相對(duì)引用是 指定待引用模塊與當(dāng)前文件的相對(duì)位置,.表示上一級(jí)文件
在這樣的文件結(jié)構(gòu)下
trymodule
│ first.py
├───folder1
│ │ abcd.py
│ │ __init__.py
復(fù)制代碼
編寫(xiě)__init__.py文件,其中要引用abcd.py文件中的變量
絕對(duì)引用是from folder1.abcd import b
相對(duì)引用是from .abcd import b
相對(duì)引用中,.是指父文件(也有from . import xxx的用法),.xxx是指同一層文件,..xxx則是與父文件夾同級(jí)的xxx文件(多一個(gè).表示多往上一層)
一般用哪個(gè)呢?
python3之后官方推薦用絕對(duì)引用的方式,只有當(dāng)模塊中文件關(guān)系非常復(fù)雜時(shí)相對(duì)引用才會(huì)有優(yōu)勢(shì)。
import運(yùn)行本質(zhì)
使用import語(yǔ)句,要明確兩件事
(1)執(zhí)行導(dǎo)入模塊命令時(shí),會(huì)首先檢查待導(dǎo)入的模塊是否在當(dāng)前已有模塊之中,如果有則跳過(guò)import。因此模塊之間相互引用不會(huì)導(dǎo)致無(wú)限循環(huán)。
查看當(dāng)前已導(dǎo)入模塊使用下面方法
import sys
sys.modules
復(fù)制代碼
得到結(jié)果是一個(gè)字典,鍵是模塊名,值是文件所在路徑
(2)import語(yǔ)句與文件執(zhí)行
在這樣的文件結(jié)構(gòu)下
trymodule
│ first.py
├───folder1
│ │ abcd.py
│ │ __init__.py
復(fù)制代碼
folder1是一個(gè)package,abcd是一個(gè)module
import folder1 只是導(dǎo)入package,相當(dāng)于執(zhí)行__init__.py文件
from folder import abcd則執(zhí)行了__init__.py文件文件與abcd.py文件
from folder1.abcd import b其實(shí)也執(zhí)行了__init__.py文件文件與abcd.py文件
(要知道執(zhí)行了什么,可以在這些文件之中添加print語(yǔ)句,看是否打印出結(jié)果)
知道這個(gè)執(zhí)行原理,可以更好理解前面得到的一些結(jié)論
首先是在__init__.py文件中什么都沒(méi)有的情況下,import folder1無(wú)法調(diào)用abcd模塊中的變量,是因?yàn)橄喈?dāng)與運(yùn)行了一個(gè)空文件,沒(méi)有將整個(gè)包導(dǎo)入工作空間
abcd模塊中定義了print語(yǔ)句后,import兩次,只有第一次會(huì)print出值,說(shuō)明第二次檢查出模塊已在導(dǎo)入之列,忽略了這條import命令
更多運(yùn)行細(xì)節(jié)可以參考這篇文章
if __name__ == '__main__'
我們經(jīng)常會(huì)在別人的代碼中發(fā)現(xiàn)if __name__ == '__main__',為了理解它的作用,我們來(lái)看下面的例子
在folder1文件夾下新建new.py文件,里面內(nèi)容為
print(__name__)
復(fù)制代碼
在folder1文件夾下打開(kāi)命令行,輸入
python new.py
復(fù)制代碼
返回結(jié)果是__main__
在trymodule文件夾下打開(kāi)命令行,進(jìn)入python交互模式
>>> from folder1 import new
folder1.new
>>> print(__name__)
__main__
>>> print(new.__name__)
folder1.new
復(fù)制代碼
上面測(cè)試結(jié)果說(shuō)明直接運(yùn)行文件和import文件是有差異的,差異在于二者的__name__變量不同。__name__變量是一個(gè)特殊的變量,每個(gè)py文件運(yùn)行時(shí)都會(huì)對(duì)應(yīng)一個(gè)__name__變量,即使在交互模式下也可以查看這個(gè)變量值。
所以if __name__ == '__main__'的作用就很好理解了,即import時(shí)不執(zhí)行下面的代碼,只有在直接執(zhí)行這個(gè)文件時(shí)才運(yùn)行之后的代碼。這算是一種約定俗成的寫(xiě)法,如果不怕文件被import,可以不用這個(gè)。
總結(jié)
以上是生活随笔為你收集整理的python模块大全使用说明_python模块详解的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: sata接口_固态硬盘应该怎么选?是SA
- 下一篇: sqlserver安装时尽量少的占用c盘