1. 程式人生 > >Python入門六模組的使用

Python入門六模組的使用

您已經瞭解瞭如何通過定義一次函式來重用程式中的程式碼。如果您想在您編寫的其他程式中重用許多函式,該怎麼辦?您可能已經猜到,答案是模組。

有各種編寫模組的方法,但最簡單的方法是建立一個.py包含函式和變數的副檔名的檔案。

另一種方法是用編寫Python直譯器本身的本機語言編寫模組。例如,您可以使用C程式語言編寫模組,在編譯時,可以在使用標準Python直譯器時從Python程式碼中使用它們。

可以通過其他程式匯入模組以利用其功能。這也是我們如何使用Python標準庫的方法。首先,我們將瞭解如何使用標準庫模組。

示例(另存為module_using_sys.py):

import
sys print('The command line arguments are:') for i in sys.argv: print(i) print('\n\nThe PYTHONPATH is', sys.path, '\n')

輸出:

$ python module_using_sys.py we are arguments    # each arg is separated by white space
The command line arguments are:
module_using_sys.py
we
are
arguments


The PYTHONPATH is ['/tmp/py',
# many entries here, not shown here
'/Library/Python/2.7/site-packages',
'/usr/local/lib/python2.7/site-packages']

這個怎麼運作

首先,我們匯入sys使用該模組import宣告。基本上,這轉化為我們告訴Python我們想要使用這個模組。該sys模組包含與Python直譯器及其環境(即系統)相關的功能。

當Python執行import sys語句時,它會查詢sys模組。在這種情況下,它是內建模組之一,因此Python知道在哪裡找到它。

如果它不是一個已編譯的模組,即用Python編寫的模組,那麼Python直譯器將在其sys.path變數中列出的目錄中搜索它。如果找到該模組,則執行該模組正文中的語句,並使模組可供您使用。請注意,初始化僅在我們一次匯入模組時完成。

使用點分表示法訪問模組中的argv

變數。它清楚地表明該名稱是該模組的一部分。此方法的另一個優點是名稱不會與程式中使用的任何變數衝突。syssys.argvsysargv

sys.argv變數是一個列表字串(列表中詳細說明一個的後面的章節)。具體來說,它sys.argv包含命令列引數列表,即使用命令列傳遞給程式的引數。

如果使用IDE編寫和執行這些程式,請查詢在選單中為程式指定命令列引數的方法。

這裡,當我們執行時python module_using_sys.py we are arguments,我們module_using_sys.py使用python命令執行模組,接下來的其他內容是傳遞給程式的引數。Python將命令列引數儲存在sys.argv變數中供我們使用。

請記住,執行的指令碼的名稱始終是sys.argv列表中的第一個元素。所以,在這種情況下,我們將'module_using_sys.py'as sys.argv[0]'we'as sys.argv[1]'are'as sys.argv[2]'arguments'as sys.argv[3]。請注意,Python從0開始計數,而不是1。

sys.path包含其中輸入模組的目錄名的列表。注意的是,在第一個字串sys.path是空的-這個空的字串表示當前目錄也是一部分sys.path是相同PYTHONPATH的環境變數。這意味著您可以直接匯入位於當前目錄中的模組。否則,您必須將模組放在其中一個目錄中sys.path

請注意,當前目錄是啟動程式的目錄。執行import os; print(os.getcwd())以查詢程式的當前目錄。

位元組編譯的.pyc檔案

匯入模組是一個相對昂貴的事情,因此Python做了一些技巧,使其更快。一種方法是使用擴充套件建立位元組編譯的檔案,擴充套件.pyc是Python將程式轉換為的中間形式(請記住Python如何工作的介紹部分?)。.pyc當您下次從另一個程式匯入模組時,此檔案很有用 - 由於匯入模組所需的部分處理已經完成,因此速度會快得多。此外,這些位元組編譯的檔案與平臺無關。

注意:這些.pyc檔案通常與相應的.py檔案在同一目錄中建立。如果Python沒有寫入該目錄中檔案的許可權,則不會建立.pyc檔案。

from..import語句

如果要將argv變數直接匯入程式(以避免sys.每次都為其鍵入),則可以使用該from sys import argv語句。

警告:通常,請避免使用該from..import語句,import而是使用該語句。這是因為您的程式將避免名稱衝突並且更具可讀性。

例:

from math import sqrt
print("Square root of 16 is", sqrt(16))

一個模組 __name__

每個模組都有一個名稱,模組中的語句可以找出其模組的名稱。這對於確定模組是獨立執行還是正在匯入的特定目的非常方便。如前所述,當第一次匯入模組時,它包含的程式碼將被執行。我們可以使用它來使模組以不同的方式執行,具體取決於它是單獨使用還是從另一個模組匯入。這可以使用__name__模組的屬性來實現。

示例(另存為module_using_name.py):

if __name__ == '__main__':
    print('This program is being run by itself')
else:
    print('I am being imported from another module')

輸出:

$ python module_using_name.py
This program is being run by itself

$ python
>>> import module_using_name
I am being imported from another module
>>>

這個怎麼運作

每個Python模組都有自己的__name__定義。如果是這樣'__main__',則意味著模組由使用者獨立執行,我們可以採取適當的措施。

製作自己的模組

建立自己的模組很簡單,你一直在做這些!這是因為每個Python程式也是一個模組。你只需要確保它有一個.py副檔名。以下示例應該清楚說明。

示例(另存為mymodule.py):

def say_hi():
    print('Hi, this is mymodule speaking.')

__version__ = '0.1'

以上是一個示例模組。正如您所看到的,與我們通常的Python程式相比,它沒有什麼特別之處。接下來我們將看到如何在我們的其他Python程式中使用此模組。

請記住,模組應該放在與我們匯入它的程式相同的目錄中,或者放在其中一個目錄中sys.path

另一個模組(另存為mymodule_demo.py):

import mymodule

mymodule.say_hi()
print('Version', mymodule.__version__)

輸出:

$ python mymodule_demo.py
Hi, this is mymodule speaking.
Version 0.1

這個怎麼運作

請注意,我們使用相同的點分表示法來訪問模組的成員。Python可以很好地重用相同的符號來賦予它獨特的“Pythonic”感覺,這樣我們就不必繼續學習新的方法來做事。

這是一個使用from..import語法的版本(另存為mymodule_demo2.py):

from mymodule import say_hi, __version__

say_hi()
print('Version', __version__)

輸出與輸出mymodule_demo2.py相同mymodule_demo.py

請注意,如果__version__在匯入mymodule的模組中已經聲明瞭名稱,則會發生衝突。這也可能是因為每個模組通常使用此名稱宣告其版本號。因此,總是建議您更喜歡該import語句,即使它可能會使您的程式更長一些。

你也可以使用:

from mymodule import *

這將匯入所有公共名稱,例如say_hi但不會匯入,__version__因為它以雙下劃線開頭。

警告:請記住,您應該避免使用import-star,即from mymodule import *

Python的禪宗

Python的指導原則之一是“明確比隱含更好”。import this在Python中執行以瞭解更多資訊。

dir功能

內建dir()函式返回物件定義的名稱列表。如果物件是模組,則此列表包括在該模組內定義的函式,類和變數。

此函式可以接受引數。如果引數是模組的名稱,則該函式返回該指定模組的名稱列表。如果沒有引數,則該函式返回當前模組的名稱列表。

例:

$ python
>>> import sys

# get names of attributes in sys module
>>> dir(sys)
['__displayhook__', '__doc__',
'argv', 'builtin_module_names',
'version', 'version_info']
# only few entries shown here

# get names of attributes for current module
>>> dir()
['__builtins__', '__doc__',
'__name__', '__package__', 'sys']

# create a new variable 'a'
>>> a = 5

>>> dir()
['__builtins__', '__doc__', '__name__', '__package__', 'sys', 'a']

# delete/remove a name
>>> del a

>>> dir()
['__builtins__', '__doc__', '__name__', '__package__', 'sys']

這個怎麼運作

首先,我們看到dir匯入sys模組的用法。我們可以看到它包含的巨大屬性列表。

接下來,我們使用該dir函式而不向其傳遞引數。預設情況下,它返回當前模組的屬性列表。請注意,匯入的模組列表也是此列表的一部分。

為了觀察dir實際操作,我們定義一個新變數a併為其賦值,然後檢查dir並觀察到同名列表中還有一個附加值。我們使用del語句刪除當前模組的變數/屬性,並且更改將再次反映在dir函式的輸出中。

關於以下內容的註釋del:此語句用於刪除變數/名稱,並且在語句執行後,在這種情況下del a,您無法再訪問該變數a- 就好像它之前從未存在過一樣。

請注意,該dir()函式適用於任何物件。例如,執行(字串)類dir(str)的屬性str

還有一個vars()函式可以為您提供屬性及其值,但它不適用於所有情況。

到目前為止,您必須已經開始觀察組織程式的層次結構。變數通常進入函式內部。函式和全域性變數通常都在模組內部。如果你想組織模組怎麼辦?這就是包裝進入圖片的地方。

包只是模組的資料夾,帶有一個特殊__init__.py檔案,向Python指示該資料夾是特殊的,因為它包含Python模組。

假設您想要建立一個名為'world'的包,包含'asia','africa'等子包,這些子包又包含'india','madagascar'等模組。

這是你如何構建資料夾:

- <some folder present in the sys.path>/
    - world/
        - __init__.py
        - asia/
            - __init__.py
            - india/
                - __init__.py
                - foo.py
        - africa/
            - __init__.py
            - madagascar/
                - __init__.py
                - bar.py

包只是分層組織模組的便利。您將在標準庫中看到許多此類例項。

摘要

就像函式是程式的可重用部分一樣,模組也是可重用的程式。包是組織模組的另一個層次結構。Python附帶的標準庫就是這樣一組包和模組的一個例子。

我們已經瞭解瞭如何使用這些模組並建立自己的模組。

接下來,我們將學習一些稱為資料結構的有趣概念。