Python3簡明教程(十二)—— 模塊


在這節我們將要學習 Python 模塊相關知識。包括模塊的概念和導入方法,包的概念和使用,第三方模塊的介紹,命令行參數的使用等。

模塊

到目前為止,我們在 Python 解釋器中寫的所有代碼都在我們退出解釋器的時候丟失了。但是當人們編寫大型程序的時候他們會傾向於將代碼分為多個不同的文件以便使用,調試以及擁有更好的可讀性。在 Python 中我們使用模塊來到達這些目的。模塊是包括 Python 定義和聲明的文件。文件名就是模塊名加上 .py 后綴。

你可以由全局變量 __name__ 得到模塊的模塊名(一個字符串)。

現在我們來看看模塊是怎樣工作的。創建一個 bars.py 文件。文件內容如下:

"""
Bars Module
============
這是一個打印不同分割線的示例模塊
"""
def starbar(num):
    """打印 * 分割線

    :arg num: 線長
    """
    print('*' * num)

def hashbar(num):
    """打印 # 分割線

    :arg num: 線長
    """
    print('#' * num)

def simplebar(num):
    """打印 - 分割線

現在我們啟動解釋器然后導入我們的模塊。

>>> import bars
>>>

我們必須使用模塊名來訪問模塊內的函數。

>>> bars.hashbar(10)
##########
>>> bars.simplebar(10)
----------
>>> bars.starbar(10)
**********

導入模塊

有不同的方式導入模塊。我們已經看到過一種了。你甚至可以從模塊中導入指定的函數。這樣做:

>>> from bars import simplebar, starbar
>>> simplebar(20)
--------------------

你也可以使用 from module import * 導入模塊中的所有定義,然而這並不是推薦的做法。

 

含有 __init__.py 文件的目錄可以用來作為一個包,目錄里的所有 .py 文件都是這個包的子模塊。

本節實驗將創建下面的 mymodule 目錄,目錄結構如下:

shiyanlou:~/ $ tree mymodule[16:57:21]
mymodule
├── bars.py
├── __init__.py
└── utils.py

0 directories, 3 files

在這個例子中,mymodule 是一個包名並且 bars 和 utils是里面的兩個子模塊。

首先創建 mymodule 目錄:

$ cd /home/shiyanlou
$ mkdir mymodule

然后將上一節編寫的 bars.py 拷貝到 mymodule 目錄下(可以用cp指令),然后可以使用 touch 創建一個 utils.py 文件。使用 touch 命令創建一個空的 __init__.py 文件。

如果 __init__.py 文件內有一個名為 __all__ 的列表,那么只有在列表內列出的名字將會被公開。

因此如果 mymodule 內的 __init__.py 文件含有以下內容:

from mymodule.bars import simplebar
__all__ = [simplebar, ]

那么導入時將只有 simplebar 可用。如果你在 python3 解釋器中進行測試,需要確定是在 mymodule 目錄同級的目錄下執行的 python3,類似下面的操作,否則會出現 ImportError: No module named 'mymodule' 的報錯。

$ cd /home/shiyanlou
$ python3
>>>

from mymodule import * 只能工作在模塊級別的對象上,試圖導入函數或類將導致 syntax error。

 

默認模塊

現在你安裝 Python 的時候會附帶安裝不同的模塊,你可以按需使用它們,也可以為其它特殊用途安裝新模塊。在下面的幾個例子中,我們將要看到同樣例子很多。

上面的例子展示了怎樣獲得你系統中安裝的所有模塊的列表。在這里就不粘貼它們了,因為這是一個很大的列表。

你也能在解釋器里使用 help() 函數查找任何模塊/類的文檔。如果你想要知道字符串所有可用的方法,你可以像下面這樣做:

>>> help(str)

os模塊

os 模塊提供了與操作系統相關的功能。你可以使用如下語句導入它:

>>> import os

getuid() 函數返回當前進程的有效用戶 id。

>>> os.getuid()
5000

getpid() 函數返回當前進程的 id。getppid() 返回父進程的 id。

>>> os.getpid()
384
>>> os.getppid()
235

uname() 函數返回識別操作系統的不同信息,在 Linux 中它返回的詳細信息可以從 uname -a 命令得到。uname() 返回的對象是一個元組,(sysname, nodename, release, version, machine)

>>> os.uname()
posix.uname_result(sysname='Linux', nodename='eca189f0062c', release='
4.4.0-93-generic', version='#116~14.04.1-Ubuntu SMP Mon Aug 14 16:07:0
5 UTC 2017', machine='x86_64')

getcwd() 函數返回當前工作目錄。chdir(path) 則是更改當前目錄到 path。在例子中我們首先看到當前工作目錄是 /home/shiyanlou,然后我們更改當前工作目錄到 /Code並再一次查看當前工作目錄。

>>> os.getcwd()
'/home/shiyanlou'
>>> os.chdir('Code')
>>> os.getcwd()
'/home/shiyanlou/Code'

所以現在讓我們使用 os 模塊提供的另一個函數來創建一個自己的函數,它將列出給定目錄下的所有文件和目錄。

def view_dir(path='.'):
    """
    這個函數打印給定目錄中的所有文件和目錄
    :args path: 指定目錄,默認為當前目錄
    """
    names = os.listdir(path)
    names.sort()
    for name in names:
        print(name, end =' ')
    print()

使用例子中的 view_dir() 函數。

>>> view_dir('/')
.bashrc .dockerenv .profile bin boot dev etc home lib lib64 media mnt opt proc root run sbin srv sys tmp usr var

os 模塊還有許多非常有用的函數,你可以在這里閱讀相關內容。

 

Requests模塊

Requests 是一個第三方 Python 模塊,其官網的介紹如下:

Requests 唯一的一個非轉基因的 Python HTTP 庫,人類可以安全享用。

警告:非專業使用其他 HTTP 庫會導致危險的副作用,包括:安全缺陷症、冗余代碼症、重新發明輪子症、啃文檔症、抑郁、頭疼、甚至死亡。

第三方模塊並不是默認的模塊,意味着你需要安裝它,我們使用 pip3 安裝它。

首先要安裝 pip3

$ sudo apt-get update
$ sudo apt-get install python3-pip

然后用 pip3 安裝 requests

$ sudo pip3 install requests

上面的命令會在你的系統中安裝 Python3 版本的 Requests 模塊。

獲得一個簡單的網頁

你可以使用 get() 方法獲取任意一個網頁。

>>> import requests
>>> req = requests.get('https://github.com')
>>> req.status_code
200

req 的 text 屬性存有服務器返回的 HTML 網頁,由於 HTML 文本太長就不在這里貼出來了。

使用這個知識,讓我們寫一個能夠從指定的 URL 中下載文件的程序。

代碼寫入文件 /home/shiyanlou/download.py

#!/usr/bin/env python3
import requests

def download(url):
    '''
    從指定的 URL 中下載文件並存儲到當前目錄
    url: 要下載頁面內容的網址
    '''
    # 檢查 URL 是否存在
    try:
        req = requests.get(url)
    except requests.exceptions.MissingSchema:
        print('Invalid URL "{}"'.format(url))
        return
    # 檢查是否成功訪問了該網站
    if req.status_code == 403:
        print('You do not have the authority to access this page.')
        return
    filename = url.split('/')[-1]
    with open(filename, 'w') as fobj:
        fobj.write(req.content.decode('utf-8'))
    print("Download over.")

if __name__ == '__main__':
    url = input('Enter a URL: ')
    download(url)

測試一下程序:

可以看到目錄下已經多了一個 sample.txt 文件。

你可能已經注意到了 if __name__ == '__main__': 這條語句,它的作用是,只有在當前模塊名為 __main__ 的時候(即作為腳本執行的時候)才會執行此 if 塊內的語句。換句話說,當此文件以模塊的形式導入到其它文件中時,if塊內的語句並不會執行。

你可以將上面的程序修改的更友好些。舉個例子,你可以檢查當前目錄是否已存在相同的文件名。os.path 模塊可以幫助你完成這個。

 

argparse命令行參數處理模塊

你還記得 ls 命令嗎,你可以傳遞不同的選項作為命令行參數。

這里是用到的模塊是 sys,命令行傳入的所有參數都可以使用 sys.argv 獲取。如果希望對參數進行處理可以使用 argparse 模塊,閱讀這篇 文檔 學習。

 

tab補全

首先創建一個文件:~/.pythonrc ,文件內寫入如下內容:

import rlcompleter, readline
readline.parse_and_bind('tab: complete')


history_file = os.path.expanduser('~/.python_history')
readline.read_history_file(history_file)

import atexit
atexit.register(readline.write_history_file, history_file)

下一步在 ~/.bashrc 文件中設置 PYTHONSTARTUP 環境變量指向這個文件:

$ export PYTHONSTARTUP=~/.pythonrc

現在,從今以后每當你打開 bash shell,你將會有 TAB 補全和 Python 解釋器中代碼輸入的歷史記錄。

要在當前 shell 中使用,source 這個 bashrc 文件。

$ source ~/.bashrc

 

總結

Python 吸引人的一點是其有眾多的模塊可以使用,對於自帶模塊,可以看看 Python3 的官方文檔,對於第三方模塊,可以在 PyPI 上找找。很多時候你都能找到合適的包幫你優雅的完成部分工作。比如 argparse 模塊幫你非常容易的編寫用戶友好的命令行接口。

 

 

參考鏈接:https://www.shiyanlou.com/courses/596

 


注意!

本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系我们删除。



 
粤ICP备14056181号  © 2014-2020 ITdaan.com