1. 程式人生 > >python 小白(無編程基礎,無計算機基礎)的開發之路 輔助知識2 模塊

python 小白(無編程基礎,無計算機基礎)的開發之路 輔助知識2 模塊

sys.path 程序啟動 及其 一般來說 adding 名稱空間 nbsp 運行時 strong

一、模塊和命名空間

一般來說,Python程序往往由多個模塊文件構成,通過import語句連接在一起。每個模塊文件是一個獨立完備的變量包,即一個命名空間。一個模塊文件不能看到其他文件定義的變量名,除非它顯示地導入了那個文件,所以模塊文件在代碼文件中起到了最小化命名沖突的作用。因為每個文件都是一個獨立完備的命名空間,即使在他們拼寫相同的情況下,一個文件的變量名是不會與另一個文件中的變量沖突的。

註意:import VS from:應該指出,from語句在某種意義上戰勝了模塊的名稱空間分割的目的,因為from把變量從一個文件復制到另一個文件,這可能導致在導入的文件中相同名稱的變量被覆蓋(並且,如果發生這種情況的話,不會為你給出警告)。這根本上會導致名稱空間重疊到一起,至少在復制的變量上會重疊。

二、模塊介紹

模塊:用來從邏輯上組織Python代碼(變量,函數,類,邏輯:實現一個功能),本質就是.py結尾的Python文件(文件名:test.py,對應的模塊名:test)

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

模塊分類:
  內置模塊
  自定義模塊
  第三方模塊(需要安裝才能使用)


註意:Python中的模塊,在其他語言中叫做類庫。

三、模塊導入和重載

導入和重載提供了一種自然的程序啟動的選擇,因為導入操作將會在最後一步執行文件。

在典型的應用中,導入者得到了模塊文件中在頂層所定義的所有變量名。這些變量名通常被賦值給通過模塊函數、類、變量以及其他被導出的工具。這些往往都會在其他文件或程序中使用。表面上來看,一個模塊文件的變量名可以通過兩個Python語句讀取--import和from,以及reload調用。

3.1、模塊的顯要特性:屬性
從一般意義上來說,模塊往往就是變量名的封裝,被認作是命名空間。在一個包中的變量名就是所謂的屬性:也就是說,屬性就是綁定在特定的對象上的變量名。

舉個例子,使用文本編輯器創建一個名為myfile.py的單行的Python模塊文件,其內容如下:

1 2 3 4 # cat myfile.py #!/usr/bin/env python3.5 title = "The Meaning of Life"

當文件導入時,它的代碼運行並生成了模塊的屬性。這個賦值語句創建了一個名為title的模塊的屬性。

可以通過兩種不同的方法從其他組件獲得這個模塊的title屬性:
第一種,可以通過使用import語句將模塊作為一個整體載入,並使用模塊名後跟一個屬性名來獲取它:

1 2 3 >>> import myfile >>> print(myfile.title) The Meaning of Life

一般來說,這裏的點號表達式代表了object.attribute的語法,可以從任何的object中取出其任意的屬性,並且這是Python代碼中的一個常用操作。在這裏,我們已經使用了它去獲取在模塊myfile中的一個字符串變量title,即myfile.titile。

註意:一旦以import方法導入模塊文件,內置的dir函數可以獲得模塊內部的可用的變量名的列表。

第二種,可以通過from語句從模塊文件中獲得(實際上是復制)變量名:(推薦)

1 2 3 >>> from myfile import title >>> print(title) The Meaning of Life

from和import很相似,只不過增加了對載入組件的變量名的額外的賦值。從技術上講,from復制了模塊的屬性,以便屬性能夠成為接收者的直接變量。因此,能夠直接以title(一個變量)引用導入字符串而不是myfile.title(一個屬性引用)。

無論使用的是import還是from去執行導入操作,模塊文件myfile.py的語句都會執行,並且導入的組件(對應這裏是交互式提示模式)在頂層文件中得到了變量名的讀取權。也許在這個簡單的例子中只有一個變量名(變量title被賦值給一個字符串),但是如果開始在模塊中定義對象,例如,函數和類時,這個概念將會很有用。這樣一些對象就變成了可重要的組件,可以通過變量名被一個或多個客戶端模塊讀取。

在實際應用中,模塊文件往往定義了一個以上的可被外部文件使用的變量名。

註意:import和from列出模塊名時,都是使用myfile,沒有.py後綴。這是因為Python在尋找實際文件時,依靠Python模塊搜索的路徑定位文件,找到後自動中加入後綴名。然而,系統shell命令行中,一定要記得加上後綴名,但是import語句中則不用。

3.2、導入模塊的所有方法:

1 2 3 4 5 6 import module_name #表示將模塊中的所有代碼加載到這個位置並賦值給變量module_name,並執行模塊 import libs.module_name #表示從libs目錄下導入模塊文件module_name,調用方法:libs.module_name.func() import module1_name,module2_name #同時導入多個模塊 from module_name import login,logout #相當於將module_name\login中的代碼拿到當前位置執行 from module_name import login as module_name_login #對導入模塊中的方法取別名 from libs.module_name import func #從目錄下的模塊文件中導入方法func,調用:func()

import本質:
  導入模塊的本質就是把Python文件解釋一遍。
  導入包的本質就是執行該包下的__init__.py文件。

導入優化:
  from module_name import login
  相比較import module_name,調用時module_name.test(),每次調用時都需要在os.path路徑中檢索導致效率降低,所以使用from...import...導入,這樣相當於將方法直接拿到調用者中執行。

技術分享 示例

3.3、import如何工作
導入其實是運行時的運算,程序第一次導入指定文件時,會執行三個步驟:
  a、找到模塊文件
  b、編譯成位碼(需要時)
  c、執行模塊的代碼來創建其所定義的對象
這三個步驟只在程序執行時,模塊第一次導入時才會進行。在這之後,導入相同模塊時,會跳過這三個步驟,而只提取內存中已加載的模塊對象。python把載入的模塊存儲到一個名為sys.modules的表中(list(sys.modules.keys())),並在一次導入操作的開始檢查該表。如果模塊不存在,將會啟動一個三個步驟的過程。

a、搜索

首先,Python必須查找到import語句所引用的模塊文件。事實上,路徑和後綴是刻意省略掉的,因為Python使用了標準模塊搜索路徑來找出import語句所對應的模塊文件。

Python的模塊查找路徑:

1 2 3 4 import sys for item in sys.path:   print(item)

  

Python模塊的查找順序:

1 2 3 4 5 6 7 8 依次從上往下查找(上面的優先,且不再搜索後續路徑),如果都沒有找到,就報錯。 D:\oldboy\s14\day5 #執行腳本所在目錄 D:\oldboy\s14 #忽略這個目錄,因為這個目錄是因為pycharm自行添加的 C:\Users\chen\AppData\Local\Programs\Python\Python35\python35.zip C:\Users\chen\AppData\Local\Programs\Python\Python35\DLLs C:\Users\chen\AppData\Local\Programs\Python\Python35\lib C:\Users\chen\AppData\Local\Programs\Python\Python35 C:\Users\chen\AppData\Local\Programs\Python\Python35\lib\site-packages

註意:sys.path返回的結果是一個列表,當我們需要添加路徑時,只需要向列表中追加即可。

修改Python的模塊查找路徑:

1 2 示例:__file__表示當前文件 sys.path.append(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))


模塊文件選擇:

1 2 3 4 5 6 7 8 9 10 11 文件名的後綴(例如,.py)是刻意從import語句中省略的。Python會選擇在搜索路徑中第一個符合導入文件名的文件。例如,import b形式的import敘述可能會加載。 源代碼文件b.py 字節碼文件b.pyc 目錄b,包導入 編譯擴展模塊(通常用C或C++編寫),導入時使用動態連接(例如,Linux的b.so以及windows的b.dll) 用C編寫的編譯好的內置模塊,並通過靜態連接至Python。 ZIP文件組件,導入時會自動解壓縮。 內存內映像,對於frozen可執行文件。 java類,在jython版本的Python中。 .NET組件,在IronPython版本的Python中。

b、編譯(可選)
遍歷模塊搜索路徑,找到符合import語句的源代碼文件後,如果有必要的話,Python接下來會將其編譯成字節碼。

Python會檢查文件的時間戳,如果發現字節碼文件比源代碼文件舊(例如,如果你修改過源文件),就會在程序運行時自動重新生成字節代碼。否則,就會跳過源代碼到字節碼的編譯步驟。


c、運行
import操作的最後步驟是執行模塊的字節碼。文件中所有語句會依次執行,從頭到尾,而此步驟中任何對變量名的賦值運算,都會產生所得到的模塊文件的屬性。因此,這個執行步驟會生成模塊代碼所定義的所有工具。例如,文件中的def語句會在導入時執行,來創建函數,並將模塊內的屬性賦值給那些函數。之後,函數就能被程序中這個文件的導入者來調用。


3.4、重載
在默認情況下,只是在每次會話的第一次運行。在第一次導入之後,其他的導入都不會再工作,甚至在另一個窗口中改變並保存了模塊的源代碼文件也不行。

1 2 3 4 5 6 7 8 9 10 $ cat script1.py #!/usr/bin/env python3 print(‘hello world‘) $ python3 >>> import script1 # 第一次導入操作完成後,會執行文件 hello world >>> import script1 # 第二次導入不會執行 >>>

因為導入時一個開銷很大的操作,以至於每個文件、每個程序運行不能夠重復多於一次。導入必須找到文件,將其編譯成字節碼,並且運行代碼。

但是,如果真的想要Python在同一次會話中再次運行文件(不停止和重新啟動會話),需要調用imp標準庫模塊中可用的reload函數。reload函數載入並運行了文件最新版本的代碼,如果已經在另一個窗口中修改並保存了它,那將反應出修改變化。

1 2 3 4 5 >>> from imp import reload >>> reload(script1) hello world <module ‘script1‘ from ‘/home/chen/script1.py‘>

python 小白(無編程基礎,無計算機基礎)的開發之路 輔助知識2 模塊