【Python學習】python學習手冊--第二十四章 高級模塊話題

在模塊中隱藏數據

在模塊文件中,可以將變量名前加下劃線(比如_X),可以防止在使用from * 語句導入該模塊時,將那些下劃線的變量名複製過去。這種方式並不是私有的聲明,還是有其他方式獲得這種下劃線的變量名,比如import等等。
你還可以將變量名放在模塊頂層的列表__all__中,以達到類似的相關,需要注意的是,用from * 執行變量導入時,只會複製__all__列表中的變量,這恰恰與下劃線變量的作用相反。

模塊屬性__name__

每一個模塊都有一個名爲name的屬性:

  • 如果該文件是以頂層文件執行,那麼該模塊的__name__屬性就會設置成爲“__main__”。
  • 如果該文件是以模塊的方式導入其它文件,__name__就會改設成爲客戶端所瞭解的模塊名。

實際上,屬性”__name__”變量充當一個使用模式標誌,它用來識別該程序是用作模塊導入的還是用作頂層文件執行的。所以經常會看到 if __name__ == “__main__”的判斷,當前模塊如果用做頂層腳本執行時,就運行該if複合語句下的代碼塊,相反作爲模塊導入時,就不會執行。這種判斷通常用於單元測試用

import 和from語句的as擴展

使用方法:

import modul as name

相當於

import modul
name = modul
del modul

from語句也可以使用:

from modul import name2 as name3
name3.func()                      #相當於直接調用name2中的函數func()

用字符串來指定導入模塊

模塊是對象,如果通過一個變量保存模塊的名稱,如何執行導入?

>>> import "string"          #無法直接通過字符串來導入模塊
  File "<stdin>", line 1
    import "string"
                  ^
SyntaxError: invalid syntax
>>> x='string'                   
>>> import x
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ImportError: No module named 'x'
>>> 

爲了解決這種問題,我們可以構建一個Python語句的字符串,通過動態構建這個字符串來指定要導入的模塊,再通過exec函數來執行”Python代碼”。

>>> x='string'   
>>> exec("import "+x)
>>> string
<module 'string' from '/usr/lib/python3.5/string.py'>
>>> 

exec的缺點是每次執行這個命令時都會去編譯語句。如果使用一個內置的__import__語句來執行導入,代碼運行速度應該會更快。

>>> nodename="string"   
>>> string=__import__(nodename)          #需要注意的是改內置函數會返回模塊對象,需要將它保存於一個變量中。
>>> string
<module 'string' from '/usr/lib/python3.5/string.py'>
>>> 

模塊設計理念

  • 總是在Python模塊內部編寫Python代碼。
  • 模塊的耦合性要降到最低:各個模塊之間的變量儘量可能減少聯繫。模塊應該封閉成爲盒子,運行起來纔會有最好的效果。
  • 最大化模塊的粘合性:統一目標
  • 模塊應該減少去修改其它模塊的變量。

模塊還有一些注意事項:

  • 模塊頂層的代碼都是按照順序執行,這意味着頂層的代碼無法引用文件後面才聲明的變量。但是函數內部可以引用整個模塊中賦值過的變量或其它函數
  • from語句是複製相同的變量名,相當於同變量名的拷貝。
  • reload不會影響from語句的導入,reload只是改變模塊對象,而from是對模塊內變量的拷貝,拷貝後並不會因模塊本身改變而改變(import語句就不行了)
  • 當不同模塊內有相同變量名時,必須使用import語句,這樣使得調用變量時,加上必要的模塊名稱(命名空間)以區別使用的同名變量
  • 當使用遞歸導入(模塊A需要導入模塊B,而模塊B又需要導入模塊A)時,不要使用from語句,要使用import。在設計模塊時,要避免這種導入的發生。這種導入很少見。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章