代碼庫和插件 FAQ?

目錄

通用的代碼庫問(wèn)題?

如何找到可以用來(lái)做 XXX 的模塊或應用??

代碼庫參考 中查找是否有適合的標準庫模塊。(如果你已經(jīng)了解標準庫的內容,可以跳過(guò)這一步)

對于第三方軟件包,請搜索 Python Package Index 或者是嘗試 Google 或其他網(wǎng)絡(luò )搜索引擎。 搜索 "Python" 加上一兩個(gè)你感興趣的關(guān)鍵詞通常就會(huì )找到一些有用的信息。

math.py(socket.py,regex.py 等)的源文件在哪??

如果找不到模塊的源文件,可能它是一個(gè)內建的模塊,或是使用 C,C++ 或其他編譯型語(yǔ)言實(shí)現的動(dòng)態(tài)加載模塊。這種情況下可能是沒(méi)有源碼文件的,類(lèi)似 mathmodule.c 這樣的文件會(huì )存放在 C 代碼目錄中(但不在 Python 目錄中)。

Python 中(至少)有三類(lèi)模塊:

  1. 使用 Python 編寫(xiě)的模塊(.py);

  2. 使用 C 編寫(xiě)的動(dòng)態(tài)加載模塊(.dll,.pyd,.so,.sl 等);

  3. 使用 C 編寫(xiě)并鏈接到解釋器的模塊,要獲取此列表,輸入:

    import sys
    print(sys.builtin_module_names)
    

在 Unix 中怎樣讓 Python 腳本可執行??

你需要做兩件事:文件必須是可執行的,并且第一行需要以 #! 開(kāi)頭,后面跟上 Python 解釋器的路徑。

第一點(diǎn)可以用執行 chmod +x scriptfile 或是 chmod 755 scriptfile 做到。

第二點(diǎn)有很多種做法,最直接的方式是:

#!/usr/local/bin/python

在文件第一行,使用你所在平臺上的 Python 解釋器的路徑。

如果你希望腳本不依賴(lài) Python 解釋器的具體路徑,你也可以使用 env 程序。假設你的 Python 解釋器所在目錄已經(jīng)添加到了 PATH 環(huán)境變量中,幾乎所有的類(lèi) Unix 系統都支持下面的寫(xiě)法:

#!/usr/bin/env python

不要 在 CGI 腳本中這樣做。CGI 腳本的 PATH 環(huán)境變量通常會(huì )非常精簡(jiǎn),所以你必須使用解釋器的完整絕對路徑。

有時(shí)候,用戶(hù)的環(huán)境變量如果太長(cháng),可能會(huì )導致 /usr/bin/env 執行失??;又或者甚至根本就不存在 env 程序。在這種情況下,你可以嘗試使用下面的 hack 方法(來(lái)自 Alex Rezinsky):

#! /bin/sh
""":"
exec python $0 ${1+"$@"}
"""

這樣做有一個(gè)小小的缺點(diǎn),它會(huì )定義腳本的 __doc__ 字符串。不過(guò)可以這樣修復:

__doc__ = """...Whatever..."""

Python 中有 curses/termcap 包嗎??

對于類(lèi) Unix 系統:標準 Python 源碼發(fā)行版會(huì )在 Modules 子目錄中附帶 curses 模塊,但默認并不會(huì )編譯。(注意:在 Windows 平臺下不可用 —— Windows 中沒(méi)有 curses 模塊。)

curses 模塊支持基本的 curses 特性,同時(shí)也支持 ncurses 和 SYSV curses 中的很多額外功能,比如顏色、不同的字符集支持、填充和鼠標支持。這意味著(zhù)這個(gè)模塊不兼容只有 BSD curses 模塊的操作系統,但是目前仍在維護的系統應該都不會(huì )存在這種情況。

Python 中存在類(lèi)似 C 的 onexit() 函數的東西嗎??

atexit 模塊提供了一個(gè)與 C 的 onexit() 函數類(lèi)似的注冊函數。

為什么我的信號處理函數不能工作??

最常見(jiàn)的問(wèn)題是信號處理函數沒(méi)有正確定義參數列表。它會(huì )被這樣調用:

handler(signum, frame)

因此它應當聲明為帶有兩個(gè)形參:

def handler(signum, frame):
    ...

通用任務(wù)?

怎樣測試 Python 程序或組件??

Python 帶有兩個(gè)測試框架。doctest 模塊從模塊的 docstring 中尋找示例并執行,對比輸出是否與 docstring 中給出的是否一致。

unittest 模塊是一個(gè)模仿 Java 和 Smalltalk 測試框架的更棒的測試框架。

為了使測試更容易,你應該在程序中使用良好的模塊化設計。程序中的絕大多數功能都應該用函數或類(lèi)方法封裝 —— 有時(shí)這樣做會(huì )有額外驚喜,程序會(huì )運行得更快(因為局部變量比全局變量訪(fǎng)問(wèn)要快)。除此之外,程序應該避免依賴(lài)可變的局部變量,這會(huì )使得測試困難許多。

程序的“全局主邏輯”應該盡量簡(jiǎn)單:

if __name__ == "__main__":
    main_logic()

并放置在程序主模塊的最后面。

一旦你的程序已經(jīng)組織為一個(gè)函數和類(lèi)行為的有完整集合,你就應該編寫(xiě)測試函數來(lái)檢測這些行為。 可以將自動(dòng)執行一系列測試的測試集關(guān)聯(lián)到每個(gè)模塊。 這聽(tīng)起來(lái)似乎需要大量的工作,但是由于 Python 是如此簡(jiǎn)潔靈活因此它會(huì )極其容易。 你可以通過(guò)與“生產(chǎn)代碼”同步編寫(xiě)測試函數使編程更為愉快和有趣,因為這將更容易并更早發(fā)現代碼問(wèn)題甚至設計缺陷。

程序主模塊之外的其他“輔助模塊”中可以增加自測試的入口。

if __name__ == "__main__":
    self_test()

通過(guò)使用 Python 實(shí)現的“假”接口,即使是需要與復雜的外部接口交互的程序也可以在外部接口不可用時(shí)進(jìn)行測試。

怎樣用 docstring 創(chuàng )建文檔??

pydoc 模塊可以用 Python 源碼中的 docstring 創(chuàng )建 HTML 文件。也可以使用 epydoc 來(lái)只通過(guò) docstring 創(chuàng )建 API 文檔。Sphinx 也可以引入 docstring 的內容。

怎樣一次只獲取一個(gè)按鍵??

在類(lèi) Unix 系統中有多種方案。最直接的方法是使用 curses,但是 curses 模塊太大了,難以學(xué)習。

線(xiàn)程相關(guān)?

程序中怎樣使用線(xiàn)程??

一定要使用 threading 模塊,不要使用 _thread 模塊。threading 模塊對 _thread 模塊提供的底層線(xiàn)程原語(yǔ)做了更易用的抽象。

我的線(xiàn)程都沒(méi)有運行,為什么??

一旦主線(xiàn)程退出,所有的子線(xiàn)程都會(huì )被殺掉。你的主線(xiàn)程運行得太快了,子線(xiàn)程還沒(méi)來(lái)得及工作。

簡(jiǎn)單的解決方法是在程序中加一個(gè)時(shí)間足夠長(cháng)的 sleep,讓子線(xiàn)程能夠完成運行。

import threading, time

def thread_task(name, n):
    for i in range(n):
        print(name, i)

for i in range(10):
    T = threading.Thread(target=thread_task, args=(str(i), i))
    T.start()

time.sleep(10)  # <---------------------------!

但目前(在許多平臺上)線(xiàn)程不是并行運行的,而是按順序依次執行!原因是系統線(xiàn)程調度器在前一個(gè)線(xiàn)程阻塞之前不會(huì )啟動(dòng)新線(xiàn)程。

簡(jiǎn)單的解決方法是在運行函數的開(kāi)始處加一個(gè)時(shí)間很短的 sleep。

def thread_task(name, n):
    time.sleep(0.001)  # <--------------------!
    for i in range(n):
        print(name, i)

for i in range(10):
    T = threading.Thread(target=thread_task, args=(str(i), i))
    T.start()

time.sleep(10)

比起用 time.sleep() 猜一個(gè)合適的等待時(shí)間,使用信號量機制會(huì )更好些。有一個(gè)辦法是使用 queue 模塊創(chuàng )建一個(gè) queue 對象,讓每一個(gè)線(xiàn)程在運行結束時(shí) append 一個(gè)令牌到 queue 對象中,主線(xiàn)程中從 queue 對象中讀取與線(xiàn)程數量一致的令牌數量即可。

如何將任務(wù)分配給多個(gè)工作線(xiàn)程??

最簡(jiǎn)單的方式是使用 concurrent.futures 模塊,特別是其中的 ThreadPoolExecutor 類(lèi)。

或者,如果你想更好地控制分發(fā)算法,你也可以自己寫(xiě)邏輯實(shí)現。使用 queue 模塊來(lái)創(chuàng )建任務(wù)列表隊列。Queue 類(lèi)維護一個(gè)了一個(gè)存有對象的列表,提供了 .put(obj) 方法添加元素,并且可以用 .get() 方法獲取元素。這個(gè)類(lèi)會(huì )使用必要的加鎖操作,以此確保每個(gè)任務(wù)只會(huì )執行一次。

這是一個(gè)簡(jiǎn)單的例子:

import threading, queue, time

# The worker thread gets jobs off the queue.  When the queue is empty, it
# assumes there will be no more work and exits.
# (Realistically workers will run until terminated.)
def worker():
    print('Running worker')
    time.sleep(0.1)
    while True:
        try:
            arg = q.get(block=False)
        except queue.Empty:
            print('Worker', threading.current_thread(), end=' ')
            print('queue empty')
            break
        else:
            print('Worker', threading.current_thread(), end=' ')
            print('running with argument', arg)
            time.sleep(0.5)

# Create queue
q = queue.Queue()

# Start a pool of 5 workers
for i in range(5):
    t = threading.Thread(target=worker, name='worker %i' % (i+1))
    t.start()

# Begin adding work to the queue
for i in range(50):
    q.put(i)

# Give threads time to run
print('Main thread sleeping')
time.sleep(5)

運行時(shí)會(huì )產(chǎn)生如下輸出:

Running worker
Running worker
Running worker
Running worker
Running worker
Main thread sleeping
Worker <Thread(worker 1, started 130283832797456)> running with argument 0
Worker <Thread(worker 2, started 130283824404752)> running with argument 1
Worker <Thread(worker 3, started 130283816012048)> running with argument 2
Worker <Thread(worker 4, started 130283807619344)> running with argument 3
Worker <Thread(worker 5, started 130283799226640)> running with argument 4
Worker <Thread(worker 1, started 130283832797456)> running with argument 5
...

查看模塊的文檔以獲取更多信息;Queue 類(lèi)提供了多種接口。

怎樣修改全局變量是線(xiàn)程安全的??

Python VM 內部會(huì )使用 global interpreter lock (GIL)來(lái)確保同一時(shí)間只有一個(gè)線(xiàn)程運行。通常 Python 只會(huì )在字節碼指令之間切換線(xiàn)程;切換的頻率可以通過(guò)設置 sys.setswitchinterval() 指定。從 Python 程序的角度來(lái)看,每一條字節碼指令以及每一條指令對應的 C 代碼實(shí)現都是原子的。

理論上說(shuō),具體的結果要看具體的 PVM 字節碼實(shí)現對指令的解釋。而實(shí)際上,對內建類(lèi)型(int,list,dict 等)的共享變量的“類(lèi)原子”操作都是原子的。

舉例來(lái)說(shuō),下面的操作是原子的(L、L1、L2 是列表,D、D1、D2 是字典,x、y 是對象,i,j 是 int 變量):

L.append(x)
L1.extend(L2)
x = L[i]
x = L.pop()
L1[i:j] = L2
L.sort()
x = y
x.field = y
D[x] = y
D1.update(D2)
D.keys()

這些不是原子的:

i = i+1
L.append(L[-1])
L[i] = L[j]
D[x] = D[x] + 1

覆蓋其他對象的操作會(huì )在其他對象的引用計數變成 0 時(shí)觸發(fā)其 __del__() 方法,這可能會(huì )產(chǎn)生一些影響。對字典和列表進(jìn)行大量操作時(shí)尤其如此。如果有疑問(wèn)的話(huà),使用互斥鎖!

不能刪除全局解釋器鎖嗎??

global interpreter lock (GIL)通常被視為 Python 在高端多核服務(wù)器上開(kāi)發(fā)時(shí)的阻力,因為(幾乎)所有 Python 代碼只有在獲取到 GIL 時(shí)才能運行,所以多線(xiàn)程的 Python 程序只能有效地使用一個(gè) CPU。

在 Python 1.5 時(shí)代,Greg Stein 開(kāi)發(fā)了一個(gè)完整的補丁包(“free threadings” 補?。?,移除了 GIL,并用粒度更合適的鎖來(lái)代替。Adam Olsen 最近也在他的 python-safethread 項目里做了類(lèi)似的實(shí)驗。不幸的是,由于為了移除 GIL 而使用了大量細粒度的鎖,這兩個(gè)實(shí)驗在單線(xiàn)程測試中的性能都有明顯的下降(至少慢 30%)。

但這并意味著(zhù)你不能在多核機器上很好地使用 Python!你只需將任務(wù)劃分為多*進(jìn)程*,而不是多*線(xiàn)程*。新的 concurrent.futures 模塊中的 ProcessPoolExecutor 類(lèi)提供了一個(gè)簡(jiǎn)單的方法;如果你想對任務(wù)分發(fā)做更多控制,可以使用 multiprocessing 模塊提供的底層 API。

恰當地使用 C 拓展也很有用;使用 C 拓展處理耗時(shí)較久的任務(wù)時(shí),拓展可以在線(xiàn)程執行 C 代碼時(shí)釋放 GIL,讓其他線(xiàn)程執行。zlibhashlib 等標準庫模塊已經(jīng)這樣做了。

也有建議說(shuō) GIL 應該是解釋器狀態(tài)鎖,而不是完全的全局鎖;解釋器不應該共享對象。不幸的是,這也不可能發(fā)生。由于目前許多對象的實(shí)現都有全局的狀態(tài),因此這是一個(gè)艱巨的工作。舉例來(lái)說(shuō),小整型數和短字符串會(huì )緩存起來(lái),這些緩存將不得不移動(dòng)到解釋器狀態(tài)中。其他對象類(lèi)型都有自己的自由變量列表,這些自由變量列表也必須移動(dòng)到解釋器狀態(tài)中。等等。

我甚至懷疑這些工作是否可能在有限的時(shí)間內完成,因為同樣的問(wèn)題在第三方拓展中也會(huì )存在。第三方拓展編寫(xiě)的速度可比你將它們轉換為把全局狀態(tài)存入解釋器狀態(tài)中的速度快得多。

最后,假設多個(gè)解釋器不共享任何狀態(tài),那么這樣做比每個(gè)進(jìn)程一個(gè)解釋器好在哪里呢?

輸入與輸出?

怎樣刪除文件?(以及其他文件相關(guān)的問(wèn)題……)?

使用 os.remove(filename)os.unlink(filename)。查看 os 模塊以獲取更多文檔。這兩個(gè)函數是一樣的,unlink() 是這個(gè)函數在 Unix 系統調用中的名字。

如果要刪除目錄,應該使用 os.rmdir();使用 os.mkdir() 創(chuàng )建目錄。os.makedirs(path) 會(huì )創(chuàng )建 path 中任何不存在的目錄。os.removedirs(path) 則會(huì )刪除其中的目錄,只要它們都是空的;如果你想刪除整個(gè)目錄以及其中的內容,可以使用 shutil.rmtree()。

重命名文件可以使用 os.rename(old_path, new_path)。

如果需要截斷文件,使用 f = open(filename, "rb+") 打開(kāi)文件,然后使用 f.truncate(offset);offset 默認是當前的搜索位置。也可以對使用 os.open() 打開(kāi)的文件使用 os.ftruncate(fd, offset),其中 fd 是文件描述符(一個(gè)小的整型數)。

shutil 模塊也包含了一些處理文件的函數,包括 copyfile(),copytree()rmtree()。

怎樣復制文件??

shutil 模塊有一個(gè) copyfile() 函數。注意在 MacOS 9 中不會(huì )復制 resource fork 和 Finder info。

怎樣讀?。ɑ驅?xiě)入)二進(jìn)制數據??

要讀寫(xiě)復雜的二進(jìn)制數據格式,最好使用 struct 模塊。該模塊可以讀取包含二進(jìn)制數據(通常是數字)的字符串并轉換為 Python 對象,反之亦然。

舉例來(lái)說(shuō),下面的代碼會(huì )從文件中以大端序格式讀取一個(gè) 2 字節的整型和一個(gè) 4 字節的整型:

import struct

with open(filename, "rb") as f:
    s = f.read(8)
    x, y, z = struct.unpack(">hhl", s)

格式字符串中的 ‘>’ 強制以大端序讀取數據;字母 ‘h’ 從字符串中讀取一個(gè)“短整型”(2 字節),字母 ‘l’ 讀取一個(gè)“長(cháng)整型”(4 字節)。

對于更常規的數據(例如整型或浮點(diǎn)類(lèi)型的列表),你也可以使用 array 模塊。

備注

要讀寫(xiě)二進(jìn)制數據的話(huà),需要強制以二進(jìn)制模式打開(kāi)文件(這里為 open() 函數傳入 "rb")。如果(默認)傳入 "r" 的話(huà),文件會(huì )以文本模式打開(kāi),f.read() 會(huì )返回 str 對象,而不是 bytes 對象。

似乎 os.popen() 創(chuàng )建的管道不能使用 os.read(),這是為什么??

os.read() 是一個(gè)底層函數,它接收的是文件描述符 —— 用小整型數表示的打開(kāi)的文件。os.popen() 創(chuàng )建的是一個(gè)高級文件對象,和內建的 open() 方法返回的類(lèi)型一樣。因此,如果要從 os.popen() 創(chuàng )建的管道 p 中讀取 n 個(gè)字節的話(huà),你應該使用 p.read(n)。

怎樣訪(fǎng)問(wèn)(RS232)串口??

For Win32, OSX, Linux, BSD, Jython, IronPython:

對于 Unix,查看 Mitch Chapman 發(fā)布的帖子:

為什么關(guān)閉 sys.stdout(stdin,stderr)并不會(huì )真正關(guān)掉它??

Python 文件對象 是一個(gè)對底層 C 文件描述符的高層抽象。

對于在 Python 中通過(guò)內建的 open() 函數創(chuàng )建的多數文件對象來(lái)說(shuō),f.close() 從 Python 的角度將其標記為已關(guān)閉,并且會(huì )關(guān)閉底層的 C 文件描述符。在 f 被垃圾回收的時(shí)候,析構函數中也會(huì )自動(dòng)處理。

但由于 stdin,stdout 和 stderr 在 C 中的特殊地位,在 Python 中也會(huì )對它們做特殊處理。運行 sys.stdout.close() 會(huì )將 Python 的文件對象標記為已關(guān)閉,但是*不會(huì )*關(guān)閉與之關(guān)聯(lián)的文件描述符。

要關(guān)閉這三者的 C 文件描述符的話(huà),首先你應該確認確實(shí)需要關(guān)閉它(比如,這可能會(huì )影響到處理 I/O 的拓展)。如果確實(shí)需要這么做的話(huà),使用 os.close()

os.close(stdin.fileno())
os.close(stdout.fileno())
os.close(stderr.fileno())

或者也可以使用常量 0,1,2 代替。

網(wǎng)絡(luò ) / Internet 編程?

Python 中的 WWW 工具是什么??

參閱代碼庫參考手冊中 互聯(lián)網(wǎng)協(xié)議和支持互聯(lián)網(wǎng)數據處理 這兩章的內容。Python 有大量模塊來(lái)幫助你構建服務(wù)端和客戶(hù)端 web 系統。

Paul Boddie 維護了一份可用框架的概覽,見(jiàn) https://wiki.python.org/moin/WebProgramming 。

Cameron Laird 維護了一份關(guān)于 Python web 技術(shù)的實(shí)用網(wǎng)頁(yè)的集合,見(jiàn) http://phaseit.net/claird/comp.lang.python/web_python 。

怎樣模擬發(fā)送 CGI 表單(METHOD=POST)??

我需要通過(guò) POST 表單獲取網(wǎng)頁(yè),有什么代碼能簡(jiǎn)單做到嗎?

是的。 這里是一個(gè)使用 urllib.request 的簡(jiǎn)單例子:

#!/usr/local/bin/python

import urllib.request

# build the query string
qs = "First=Josephine&MI=Q&Last=Public"

# connect and send the server a path
req = urllib.request.urlopen('http://www.some-server.out-there'
                             '/cgi-bin/some-cgi-script', data=qs)
with req:
    msg, hdrs = req.read(), req.info()

注意,通常在百分號編碼的 POST 操作中,查詢(xún)字符串必須使用 urllib.parse.urlencode() 處理一下。舉個(gè)例子,如果要發(fā)送 name=Guy Steele, Jr. 的話(huà):

>>>
>>> import urllib.parse
>>> urllib.parse.urlencode({'name': 'Guy Steele, Jr.'})
'name=Guy+Steele%2C+Jr.'

參見(jiàn)

查看 如何利用 urllib 包獲取網(wǎng)絡(luò )資源 獲取更多示例。

生成 HTML 需要使用什么模塊??

你可以在 Web 編程 wiki 頁(yè)面 找到許多有用的鏈接。

怎樣使用 Python 腳本發(fā)送郵件??

使用 smtplib 標準庫模塊。

下面是一個(gè)很簡(jiǎn)單的交互式發(fā)送郵件的代碼。這個(gè)方法適用于任何支持 SMTP 協(xié)議的主機。

import sys, smtplib

fromaddr = input("From: ")
toaddrs  = input("To: ").split(',')
print("Enter message, end with ^D:")
msg = ''
while True:
    line = sys.stdin.readline()
    if not line:
        break
    msg += line

# The actual mail send
server = smtplib.SMTP('localhost')
server.sendmail(fromaddr, toaddrs, msg)
server.quit()

在 Unix 系統中還可以使用 sendmail。sendmail 程序的位置在不同系統中不一樣,有時(shí)是在 /usr/lib/sendmail,有時(shí)是在 /usr/sbin/sendmail。sendmail 手冊頁(yè)面會(huì )對你有所幫助。以下是示例代碼:

import os

SENDMAIL = "/usr/sbin/sendmail"  # sendmail location
p = os.popen("%s -t -i" % SENDMAIL, "w")
p.write("To: receiver@example.com\n")
p.write("Subject: test\n")
p.write("\n")  # blank line separating headers from body
p.write("Some text\n")
p.write("some more text\n")
sts = p.close()
if sts != 0:
    print("Sendmail exit status", sts)

socket 的 connect() 方法怎樣避免阻塞??

通常會(huì )用 select 模塊處理 socket 異步 I/O。

要防止 TCP 連接發(fā)生阻塞,你可以將 socket 設為非阻塞模式。 這樣當你執行 socket.connect() 時(shí),你將或是立即完成連接(不大可能)或是收到一個(gè)包含 .errno 錯誤碼的異常。 errno.EINPROGRESS 表示連接正在進(jìn)行但還沒(méi)有完成。 不同的操作系統將返回不同的值,因此你需要確認你的系統會(huì )返回什么值。

你可以使用 socket.connect_ex() 方法來(lái)避免生成異常。 它將只返回 errno 值。 要進(jìn)行輪詢(xún),你可以稍后再次調用 socket.connect_ex() -- 0errno.EISCONN 表示連接已完成 -- 或者你也可以將此 socket 傳給 select.select() 來(lái)檢查它是否可寫(xiě)。

備注

asyncio 模塊提供了通用的單線(xiàn)程并發(fā)異步庫,它可被用來(lái)編寫(xiě)非阻塞的網(wǎng)絡(luò )代碼。 第三方的 Twisted 庫是一個(gè)熱門(mén)且功能豐富的替代選擇。

數據庫?

Python 中有數據庫包的接口嗎??

有的。

標準 Python 還包含了基于磁盤(pán)的哈希接口例如 DBMGDBM 。除此之外還有 sqlite3 模塊,該模塊提供了一個(gè)輕量級的基于磁盤(pán)的關(guān)系型數據庫。

大多數關(guān)系型數據庫都已經(jīng)支持。查看 數據庫編程 wiki 頁(yè)面 獲取更多信息。

在 Python 中如何實(shí)現持久化對象??

pickle 庫模塊以一種非常通用的方式解決了這個(gè)問(wèn)題(雖然你依然不能用它保存打開(kāi)的文件、套接字或窗口之類(lèi)的東西),此外 shelve 庫模塊可使用 pickle 和 (g)dbm 來(lái)創(chuàng )建包含任意 Python 對象的持久化映射。

數學(xué)和數字?

Python 中怎樣生成隨機數??

random 標準庫模塊實(shí)現了隨機數生成器,使用起來(lái)非常簡(jiǎn)單:

import random
random.random()

這個(gè)函數會(huì )返回 [0, 1) 之間的隨機浮點(diǎn)數。

該模塊中還有許多其他的專(zhuān)門(mén)的生成器,例如:

  • randrange(a, b) 返回 [a, b) 區間內的一個(gè)整型數。

  • uniform(a, b) 返回 [a, b) 區間之間的浮點(diǎn)數。

  • normalvariate(mean, sdev) 使用正態(tài)(高斯)分布采樣。

還有一些高級函數直接對序列進(jìn)行操作,例如:

  • choice(S) 從給定的序列中隨機選擇一個(gè)元素。

  • shuffle(L) 會(huì )對列表執行原地重排,即將其隨機地打亂。

還有 Random 類(lèi),你可以將其實(shí)例化,用來(lái)創(chuàng )建多個(gè)獨立的隨機數生成器。