摘要:如果你這個腳本想要使用其它腳本里面的變量函數和類也是可以的,在你這個腳本里面用來導入要引用的腳本,而那個被引用的腳本就稱作模塊。
在此之前,我們運行一些簡短的Python代碼,都是通過Python解釋器(python或ipython)進行的,如果我們退出解釋器再重新運行解釋器后,上次敲進去的變量、函數等都不見了,沒有保存下來。為了保存我們曾經寫過的代碼,就是要寫成.py文件,稱為腳本。
如果你這個腳本想要使用其它腳本里面的變量、函數和類也是可以的,在你這個腳本里面用import來導入要引用的腳本,而那個被引用的腳本就稱作模塊(module)。
簡單來說,一個Python源碼文件(*.py)就是一個模塊。
我們的第一個Python模塊接下來,我們用文本編輯器(比如,前面介紹的VS Code)來創建一個名為?my_first_module.py的文件作為我們編寫的第一個模塊:
#!/usr/bin/env python3 # coding:utf-8 # Author: veelion # file name: my_first_module.py """My First Module""" MY_NAME = "My_First_Module" def my_print(a): print(MY_NAME, " print", a) def my_add(a, b): return a+b
我們的第一個Python模塊里面有一個全局變量:MY_NAME,兩個函數:my_print()和my_add()。接著我們在這個文件所在目錄運行Python解釋器ipython:
In [1]: import my_first_module In [2]: my_first_module? Type: module String form:File: ~/p2/tutorial/md_Python/codes/my_first_module.py Docstring: My First Module In [3]: my_first_module.MY_NAME Out[3]: "My_First_Module" In [4]: my_first_module.my_add(2, 3) Out[4]: 5 In [5]: my_first_module.my_print("猿人學") My_First_Module print 猿人學
導入模塊用import,模塊名稱就是文件名my_first_module.py去掉文件后綴.py后的名字。從上面ipython的使用中,我們可以看到模塊中的函數、變量都是可以被拿來用的。
注意:?Python模塊的文件名只能是字母、數字和下劃線,不能有-,+等其它符號,否則導入會報錯,原因很簡單,比如-符號會和Python里面的減號混淆。
把上面的模塊重命名為my-first-module.py,再import導入一下看看:
In [6]: import my-first-module File "Python模塊的二三事", line 1 import my-first-module ^ SyntaxError: invalid syntax
(1)模塊可以包含可執行的全局語句。這些語句應該是用于初始化該模塊,它們只在第一次被import時執行。我們來舉個例子,創建兩個只包含一句print的模塊:
# m1.py print("m1 is imported")
# m2.py import m1 print("m2 is imported")
在main.py中導入m1和m2這兩個模塊:
import m1 import m2 import m1 print("I am main.py")
這里m1被顯性導入兩次,還有一次被m2陰性導入,一共導入三次,那么是不是m1 is imported會被打印3次呢?我們運行這個腳本試試看:?python main.py。猜猜運行結果是怎樣的?
m1 is imported m2 is imported I am main.py
結果是只被打印了一次。這就是只在第一次被import時執行的意思。再試試把main.py中的兩個import m1都去掉,只import m2會是什么結果?
(2)每個模塊都都它自己私有的符號表,它被當做全局符號表被該模塊中所有函數使用,也就是說,每個模塊都有自己的名字空間。因此,模塊里面可以盡情(如有必要)使用全局變量,而不用擔心它們與模塊使用者的全局變量沖突。用戶使用模塊中的全局變量也很簡單:modname.itemname。
比如,my_first_module模塊中的MY_NAME使用時就是my_first_module.MY_NAME,而在你自己的腳本里面同樣可以命名MY_NAME的全局變量,而不會和my_first_module里面的沖突。
(3)模塊可以import其它模塊。模塊導入語句import不一定要在腳本的最開始,可以在代碼其它位置需要時導入。當然,在最開始導入是最清晰、規范的做法。
import 模塊的各種方式我們使用import的方式很多,前面那種?import module_name的方式是最常用的,也是代碼規范推崇的用法。從語法上講還有其它方式:
(1)用from導入部分:
In [1]: from my_first_module import my_add In [2]: my_add(1,3) Out[2]: 4 In [3]: my_print("hi") --------------------------------------------------------------------------- NameError Traceback (most recent call last)in ----> 1 my_print("hi") NameError: name "my_print" is not defined In [4]: my_first_module.my_add(1,2) --------------------------------------------------------------------------- NameError Traceback (most recent call last) in ----> 1 my_first_module.my_add(1,2) NameError: name "my_first_module" is not defined
通過from modname import xxx的方式,我們只導入了my_add,調用my_print就會出錯。并且,my_first_module模塊名稱也是未定義的,即沒有被導入。
(2)用from導入部分并重命名
跟(1)一樣,只不過把導入的名稱起了別名而已,使用時用別名:
from my_first_module import my_add as myadd
(3)用from導入全部
In [1]: from my_first_module import * In [2]: my_add(1,2) Out[2]: 3 In [3]: my_print("猿人學") My_First_Module print 猿人學 In [4]: MY_NAME Out[4]: "My_First_Module"
這種方式看似簡單,寫代碼時省去了模塊名稱my_first_module這個前綴。但是,這個省略帶來很大隱患,會限制我們自己命名。如果我們自己命名和模塊里面的名稱一樣,就會覆蓋模塊里面的名字。
這種import的方式是代碼規范嚴禁杜絕的
(4)重命名模塊
如果模塊名稱很長,我們可以給它起個短一點的別名,這樣寫代碼會簡單些:
In [1]: import my_first_module as mfm In [2]: mfm.my_add(1,2) Out[2]: 3 In [3]: mfm.my_print("猿人學") My_First_Module print 猿人學 In [4]: mfm.MY_NAME Out[4]: "My_First_Module"
這個和import my_first_module實際上一樣,只是使用的名稱變為mfm。模塊的別名可以任意起,只要和其它名稱區分開來就好。
(5)模塊重新加載
我們寫完一個模塊,可能要通過Python解釋器(如ipython)進行驗證一下,于是運行Python解釋器,import模塊,發現模塊的某個函數有錯誤,就在編輯器修改了該函數并保存該模塊文件。繼續在剛才打開的解釋器里面驗證那個有錯誤的函數,發現剛才的修改沒生效,竟然沒有生效?。。?/p>
為什么呢?為了效率,每個解釋器導入的模塊只導入一次。因此,如果你中途修改了模塊,就要出解釋器重新進入并重新導入模塊才能使修改生效。如果不退出解釋器而重新導入模塊,不管你運行多少次import modname都是無效的,因為解釋器一看這個模塊已經導入過了,就不費勁再導入一次了。解釋器懶,你就不能懶。
或者,可以不重新啟動解釋器而使用importlib.reload()重新導入。
把Python模塊當做腳本運行任何Python文件都可以這樣來運行:
python3 file.py
一個文件的Python模塊當然也可以這樣運行。一個Python文件,前面是函數的定義,定義完要運行,我們就要寫調用語句,最初你相到的可能是這樣的:
# Author: veelion # file: mylib.py def add(a, b): return a+b print(add(2, 3))
通過python mylib.py運行一下,就可以得到運行結果。
目前看起來一切正常,你看看有沒有問題?
回頭看看上面模塊二三事的第(1)條,如果這個文件當做模塊被其它文件import時,是不是也會運行打印語句?這條打印語句往往是我們為了驗證add()函數而進行的,屬于測試階段的代碼,而交付給他人作為模塊使用時,它是不需要的。那么,該怎么辦?
通過__name__屬性就可以來限制print(add(2, 3))語句的運行。文件作為腳本運行時,它的__name__屬性是__main__,而作為模塊被import時,它的__name__屬性是模塊的名稱。
先看看模塊被import時的__name__:
In [24]: import mylib 5 In [25]: mylib.__name__ Out[25]: "mylib"
我們可以看到,import mylib后打印出了5,也就是運行了print(add(2, 3))語句。
然后,我們修改mylib.py文件,把測試語句修改一下:
# Author: veelion # file: mylib.py def add(a, b): return a+b if __name__ == "__main__": print(add(2, 3))
再次在ipython解釋器里面導入該模塊時就不會打印出5,也就是那句print不再執行。
而在命令行下運行python3 mylib.py這個腳本就會執行那句print語句,因為這種執行方式下,模塊的__name__為__main__。
這些用__name__ == "__main__"條件判斷的代碼通常是該模塊的測試代碼,或者是如何使用該模塊的示例代碼。
Python模塊總結(1)一個Python文件就是一個模塊;
(2)一個模塊可以import其它模塊;
(3)在Python解釋器運行中,一個模塊只可以被import一次,除非使用importlib.reload();
(4)模塊中的可執行語句(非函數、類的定義)僅在該模塊被import時執行一次。
(5)import模塊的方式有多種,要使用最規范的方式。
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/43800.html
摘要:標準模塊附帶了一個標準模塊庫。它返回一個如果調用不傳遞參數,則列出當前已經定義的所有名字用可以查看所有的內置類型變量函數等,方法是借助標準模塊模塊高級技巧總結的搜索路徑,順序一定要搞得清編譯后的文件內置函數查看模塊定義的名字。 上一節,我們講解了Python模塊的基礎知識,這一節我們繼續深入了解模塊的更多知識,從而讓大家全面了解、掌握和運用模塊到我們實際的編程中。 在上一節中有一句話接...
摘要:所解包的序列中的元素數量必須和賦值符號左邊的變量數量完全一致。其中,冒號標識語句塊開始塊中每一個語句都是縮進相同量退回到和已經閉合的塊一樣的縮進量時,表示當前塊結束。成員資格運算符字符串和序列比較字符串可按照字母順序比較。 print和import print打印多個表達式,用逗號,隔開 print abc:, 42, nonono #輸出在每個參數之間添加空格 print在結尾處加上...
摘要:比如,模塊名表示包中名為的子模塊。例如,文件可以包含以下代碼定義了之后,就會把,,導入到當前命名空間。這種導入使用前導點來指示相對導入中涉及的當前包和父包。也就是說被執行的主程序里面不能包含相對導入。 包,Package,是一種Python模塊的集合,從文件組織形式上看,包就是一個文件夾,里面放著各種模塊(.py文件),也可以有子文件夾(子包)。包名構建了一個Python模塊的命名空間...
摘要:安裝好后,在中執行查看版本信息,應該會看到輸出如下信息版本號可能會不同如果提示未找到,則需要手動將用戶基礎目錄下的添加到中。相關文章基礎教程系列第篇開天坑啦 showImg(https://segmentfault.com/img/bV4GZu?w=1262&h=911); 之前說好的 「Odoo 基礎教程系列」終于來了(撒花)~剛過完年重新投入到工作中,一下子事情有點多都要忙不過來了...
閱讀 3792·2021-11-12 10:34
閱讀 2812·2021-09-22 15:14
閱讀 777·2019-08-30 15:53
閱讀 3195·2019-08-30 12:53
閱讀 1279·2019-08-29 18:32
閱讀 2761·2019-08-29 16:41
閱讀 1056·2019-08-26 13:40
閱讀 1795·2019-08-23 18:07