python 模塊定義、導入、優(yōu)化

轉(zhuǎn)載至:https://cloud.tencent.com/developer/article/1175296

模塊:

在Python中,一個.py文件就稱之為一個模塊(Module)。

它是實現(xiàn)了某個功能的代碼集合。

模塊分為三種:

1.自定義模塊

2.內(nèi)置標準模塊(又稱標準庫)

3.開源模塊

模塊導入方法:

1. import module_name (導入一個模塊)

2. import module_name,module2_name (導入多個模塊)

3. from module_name import * (不推薦使用)

4. from module_name import m1 as name_m1 (導入指定的函數(shù)或變量并重命名)

5. from module_name import m1,m2,m3 (導入模塊的多個函數(shù)或變量)

第3種辦法,不推薦使用。因為這一段話,相當于把module_name.py的所有代碼復制到當前代碼中,調(diào)用的時候,直接寫方法名調(diào)用,不需要module_name.方法名()這種方式調(diào)用。如果發(fā)現(xiàn)方法名或者變量沖突,以本代碼為準。

import的本質(zhì)

把導入模塊的所有代碼解釋一遍,統(tǒng)一賦值給一個變量,這個變量名叫模塊名。

調(diào)用變量,使用 module_name.變量名

調(diào)用函數(shù),使用 module_name.函數(shù)名()

from的本質(zhì)

把導入模塊的指定函數(shù)或者變量,放到當前文件的位置,執(zhí)行一遍。

調(diào)用變量或者函數(shù)的時候,直接使用即可,不需要在前面加模塊名。

自定義一個模塊

新建文件hello.py,新建文件test.py,導入模塊。注意,模塊名是去除.py之后的名字

name = "zhang"
def say_hello():
    print("hello,",name)

import hello
#輸出變量,執(zhí)行方法
print(hello.name)
hello.say_hello()
執(zhí)行輸出
zhang

hello, zhang

包:

用來從邏輯上組織模塊,本質(zhì)就是一個目錄(必須帶有一個init.py文件)

導入包的本質(zhì):

去執(zhí)行包目錄下的init.py文件

使用pycharm編輯器,新建一個包package_test

編輯init.py文件

print('from the package package_test')
新建一個文件p_test.py

import package_test
目錄結(jié)構(gòu)如下:

.
├── p_test.py
└── package_test
└── init.py
執(zhí)行p_test.py,輸出

from the package package_test

上面介紹的模塊導入,都是基于同級目錄的。那么module在不同目錄下,該如何導入呢?

目錄結(jié)構(gòu)如下:

.
├── hello.py
└── package_test
├── init.py
└── main.py
main.py需要導入hello模塊

先來分析一個導入模塊的執(zhí)行步驟

import module_name->找到module_name.py文件->找到module_name.py的路徑->sys.path(搜索路徑)

編輯main.py,打印sys.path

import sys
print(sys.path)
使用cmd執(zhí)行,執(zhí)行輸出

['E:\python_script\day5\package_test', 'C:\Program Files\Python36\python36.zip', 'C:\Program Files\Python36\DLLs', 'C:\Program Files\Python36\lib', 'C:\

\Program Files\Python36', 'C:\Program Files\Python36\lib\site-packages']

第一個元素,就是當前路徑

如果一個元素找不到,就會找下一個元素,直到所有的目錄都還找不到的話,就報錯

ModuleNotFoundError: No module named 'xxx'

為了解決這個問題,需要加一個路徑,必須要包含需要導入模塊的路徑。這個路徑,一般為項目根目錄。

編輯main.py,先來打印當前文件的絕對路徑

import sys,os
print(os.path.abspath(file))
執(zhí)行輸出

E:\python_script\day5\package_test\main.py

然后獲取當前目錄

import sys,os
print(os.path.dirname(os.path.abspath(file)))
執(zhí)行輸出

E:\python_script\day5\package_test

最后獲取上一層目錄,定義變量

import sys,os
BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(file)))
print(BASE_DIR)
執(zhí)行輸出

E:\python_script\day5

這個目錄,就可以找到package_test路徑了!

將項目根目錄添加到系統(tǒng)環(huán)境變量中

import sys,os
BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(file)))
sys.path.append(BASE_DIR)
最后導入模塊,執(zhí)行函數(shù)

import sys,os
BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(file)))
sys.path.append(BASE_DIR)

import hello

hello.say_hello()
執(zhí)行輸出

hello, zhang

注意:

sys.path.append(BASE_DIR) 是將項目根目錄追加到最后一個列表元素。如果中間某一個元素,正好找到了指定文件,比如hello.py,那么就不會再查找后面的路徑了,直接加載。

如果出現(xiàn)了這種情況,必須要把BASE_DIR插入到第一個元素位置,使用insert方法

sys.path.insert(0,BASE_DIR)
print(sys.path)
執(zhí)行輸出

['E:\python_script\day5', 'E:\python_script\day5\package_test', 'E:\python_script', 'C:\Program Files\Python36\python36.zip', 'C:\Program Files\Python36\DLLs', 'C:\Program Files\Python36\lib', 'C:\Program Files\Python36', 'C:\Program Files\Python36\lib\site-packages']

舉另外一個例子

main.py需要調(diào)用test1.py里面的函數(shù),目錄結(jié)果如下:

.
├── module_test
│ └── main.py
└── package_test
├── init.py
└── test1.py
test1.py內(nèi)容如下:

def test():
print('in the test1')
main.py直接引用package_test包,是否可以執(zhí)行呢?

import sys,os
BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(file)))
sys.path.append(BASE_DIR)

import package_test

package_test.test1.test()
執(zhí)行報錯

ModuleNotFoundError: No module named 'test1'

因為import package_test 這一步是執(zhí)行package_test目錄下的init.py文件,而這個文件是空的

修改init.py文件,從當前目錄下,導入test1模塊

這個 點 表示相對于init.py文件的路徑。

from . import test1
再次執(zhí)行main.py

執(zhí)行輸出

in the test1

再深層次的目錄調(diào)用,目錄結(jié)果如下:

python_script/
├── day4
│ └── test.py
└── day5
└── package_test
├── init.py
└── test1.py
day5的代碼,同上,沒改動

test.py需要調(diào)用test1.py,那么需要把python_script目錄加到環(huán)境變量即可

修改day4下的test.py文件

import sys,os

BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(file)))
print(BASE_DIR)
執(zhí)行輸出

E:\python_script

加載到環(huán)境變量

import sys,os

BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(file)))
sys.path.append(BASE_DIR)

from day5 import package_test
package_test.test1.test()
執(zhí)行輸出

in the test1

注意下面這行代碼

from day5 import package_test
day5表示python_script目錄下的day5

導入優(yōu)化

語法:

from 模塊名 import 函數(shù)或變量名
舉個例子,目錄結(jié)構(gòu)如下:

test4/
├── module_test.py
└── test.py
module_test.py內(nèi)容如下:

def test():
print('in the test')
test.py內(nèi)容如下:

import module_test

def logger():
module_test.test()
print('in the logger')

def search():
module_test.test()
print('in the search')

假設(shè)有N個函數(shù)在調(diào)用module_test.test()

...

logger()
執(zhí)行輸出

in the test

in the logger

module_test.test()在執(zhí)行的時候,先找到module_test模塊,再從里面檢索test函數(shù)是否存在。

那么每執(zhí)行一次,就要先找模塊,再找函數(shù),重復勞動,效率很低。

為了解決這個問題,就是在導入模塊的時候,不讓它找就可以了

import module_test
改成

from module_test import test
就可以了。

下面的執(zhí)行方法module_test.test()改成test() 就可以了,完整代碼如下

!/usr/bin/env python

coding: utf-8

author = 'www.py3study.com'

from module_test import test

def logger():
test()
print('in the logger')

def search():
test()
print('in the search')

....

logger()
執(zhí)行輸出

in the test

in the logger

這種方法,可以使代碼執(zhí)行的更快

為了避免函數(shù)重名,可以在導入的時候,起別名

from module_test import test as mod_test

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 230,362評論 6 544
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 99,577評論 3 429
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 178,486評論 0 383
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經(jīng)常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 63,852評論 1 317
  • 正文 為了忘掉前任,我火速辦了婚禮,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 72,600評論 6 412
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 55,944評論 1 328
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,944評論 3 447
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 43,108評論 0 290
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 49,652評論 1 336
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 41,385評論 3 358
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 43,616評論 1 374
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 39,111評論 5 364
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 44,798評論 3 350
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 35,205評論 0 28
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 36,537評論 1 295
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 52,334評論 3 400
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 48,570評論 2 379

推薦閱讀更多精彩內(nèi)容