帶你學python基礎:模塊和包

一、什麼是模塊

在我們平時的開發過程中,或多或少會用到 Python 的一些內置的功能,或者說,還會用到一些第三方的庫,我們用到的這些 Python 的內置的功能,和一些第三方的庫,就可以說是一些模塊了。

例如,我們在讀寫文件的時候,我們就會用到文件操作的模塊os。

是不是經常遇到呢?模塊,來了!

帶你學python基礎:模塊和包

其實,每一個 Python 腳本文件都可以被當成是一個模塊。

模塊以磁盤文件的形式存在。當一個模塊變得過大,並且驅動了太多功能的話,就應該考慮拆一些代碼出來另外建一個模塊。

模塊裏的代碼可以是一段直接執行的腳本,也可以是一堆類似庫函數的代碼,從而可以被別的模塊導 入(import)調用。模塊可以包含直接運行的代碼塊、類定義、 函數定義或這幾者的組合。

推薦所有的模塊在Python模塊的開頭部分導入。而且最好按照這樣的順序:

  • Python標準庫模塊
  • Python第三方模塊
  • 自定義模塊

帶你學python基礎:模塊和包

這個只是說約定這樣最好,其實怎樣的順序都是沒有關係的!!!

二、如何使用模塊

我想,應該知道什麼是模塊了吧!

那好,再看看如何使用吧!

帶你學python基礎:模塊和包

在 Python 中用關鍵字import來引入某個模塊,比如要導入模塊 os,就可以在文件最開始的地方用import os來引入。下面,看一個簡單的例子。

# 導入系統os模塊
import os

# 列出目錄下的文件
files = os.listdir('F:\\人工智能\\2018北風網人工智能(完結)\\三、python基礎(1)\\學習PPT\\學習PPT')
print(files)

這個例子中,我們導入了系統 os 模塊,然後調用這個 os 模塊的方法,列出目標目錄下的所有文件!

import使用方法

語法

import module1 
import module2
......
import moduleN

或者

import module1[, module2[,... moduleN]]

[]:表示可選!

模塊函數調用

當我們導入了模塊之後,我們就可以通過模塊名.函數名<br/>來調用模塊中的函數了,其實,我們也可以直接函數名 調用方法即可。但是需要注意的是,如果多個模塊中都有相同的一個方法名時,我們就必須要用模塊名.函數名來調用模塊中的函數,不然會出現衝突!

例如

files = os.listdir('F:\\人工智能\\2018北風網人工智能(完結)\\三、python基礎(1)\\學習PPT\\學習PPT')

這就是調用模塊中的方法!

導入模塊中部分方法

有時候,我們並不需要導入模塊中的所有方法,所以,python的也提供了,只導入我們需要導入的方法的方式。

  • from modname import name1[, name2[, ... nameN]]

例如,要導入模塊time的sleep函數,使用如下語句。

from time import sleep, strptime

導入所有內容

from modname import*

有時候,因爲模塊的名字太長或者太複雜,可能寫的時候不太方便,所以,我們可以使用別名的方式來導入,方便編寫!

別名導入

別名導入,只需要在導入語句後面加關鍵字as

import numpy
import numpy as np  # 爲numpy取別名爲np

二、自定義模塊

既然,python可以有內置的模塊,那麼我們可不可以自定義自己的模塊呢,把自己的功能做成一個模塊豈不是美滋滋?

帶你學python基礎:模塊和包

當然沒有問題了,下面就來自己實現!

同文件夾實現

這個是說,python文件都在同一個文件夾下的情況。

現在,我們在同一個文件夾下定義兩個 python 文件,分別爲test.py,02_demo.py
帶你學python基礎:模塊和包

test.py中定義如下內容

def sum(a, b):
    return a + b

導入方法

在02_demo.py中

# 導入同文件夾下
import test

from test import sum

print(sum(1, 2))

可以看出,同一文件夾下,只需要直接導入文件名即可!

不同文件夾實現

現在有02_demo.py和在learn文件下的test02.py文件,目錄如下
帶你學python基礎:模塊和包

test02.py內容

def mul(a, b):
    return a * b

02_demo.py中跨文件夾調用

# 跨文件夾調用
import learn.test2

from learn import test2

print(test2.mul(1, 5))

不同文件夾的調用,我們發現,需要加上文件路徑,例如,test02文件在learn文件夾下,所以導入方式爲learn.test02

然而,
帶你學python基礎:模塊和包
這並不是最完美的,你想,如果項目很大,文件夾下很多的模塊,是不是每個都這樣導入,是不是會很麻煩。所以,python 中還提供了更簡單的方式--將目標路徑加入到環境當中

'''
    跨模塊引入2
'''
import sys  # 查看路徑變量

print(sys.path)
# 添加目標路徑導當前環境中
sys.path.append('.\\learn')  # 返回上一級目錄
import test2 as tt

print(tt.mul(1, 10))

是不是簡單多了!

另外,如果我們自己定義的模塊和系統模塊重名,導入的時候是會覆蓋系統的模塊哦!

例如,我們在learn文件夾下定義一個 math.py 文件
帶你學python基礎:模塊和包

math.py文件

import math

def tan(x):
    return math.tan(x) + 1

當我們導入math的時候,是會覆蓋系統的math的,導入的將是我們自定義的math。

# 覆蓋標準模塊
from learn import math

print('自定義:', math.tan(30))

import math

print('系統:', math.tan(30))

帶你學python基礎:模塊和包

最後再講一個東西,包!

三、包

既然有了模塊,爲什麼還會有包呢,包到底是什麼呢?容我一一道來。

我們都知道一個模塊通常是一個 python 文件,但是,這樣是不是顯得太零散了,如果我們出門的時候,東西太多了,是不是需要一個書包來裝一下這些東西,就更方便是不是!所以,包就是這個作用,把一些功能相近或者相似的模塊,都放在一個稱爲的地方!

帶你學python基礎:模塊和包

這個包如何?哈哈!

那麼包和模塊到底有什麼不一樣呢?

包使用

包是一個文件夾,但是,他有一個特殊之處,我們必須在這個文件夾下面定義一個__init__.py的文件,才能被程序認作是,模塊才能被導入成功。

現在我們就用一個,首先,我們新建一個名爲package的文件夾,然後再定義一個__init__.py的文件。

帶你學python基礎:模塊和包

然後,再在這個文件夾下新建 test10.pytest11.py文件,內容如下

test10.py

def subtract(x, y):
    return x - y

test11.py

def add(x, y):
    return x + y

好了,現在我們試着導包

# 導包演示

import package

print(test10.subtract(10, 10))

我們發現報錯:說我們的test10沒有定義,但是我們明明定義了,爲什麼呢?
帶你學python基礎:模塊和包

原來,在我們創建一個__init__.py文件,並且一定要在文件中寫入__all__變量,爲什麼需要這個變量呢?
帶你學python基礎:模塊和包

因爲__init__.py控制着包的導入行爲。如果__init__.py文件爲空的話,僅僅是把這個包導入,不會導入包中的模塊。__init__.py中的__all__變量,是用來*控制from包名import 時導入的模塊**。

所以,我們在__init__.py中加入__all__變量。

__all__ = ['test10', 'test11']

就正確了。
帶你學python基礎:模塊和包

包會了吧?

最後的最後,說一個小知識點。

imp.reload()

這個函數有什麼作用呢?

試想一下這樣的場景,模塊在第一次被導入之後,其他的導入都不再有效。如果此時在另一個窗口中改變並保存了模塊的源代碼文件,也無法更新該模塊。

這樣設計原因在於,導入是一個開銷很大的操作(導入必須找到文件,將其編譯成字節碼,並且運行代碼),以至於每個文件、每個程序運行不能夠重複多於一次。

當一個模塊被導入到一個腳本,模塊頂層部分的代碼只會被執行一次。
因此,如果你想重新執行模塊裏頂層部分的代碼,可以用reload()函數。該函數會重新導入之前導入過的模塊。

'''
    重新加載
'''
import test
# import test  #引入兩邊只輸出一句hahaha
import imp
imp.reload(test)  #重新導入test模塊
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章