库和扩展常见问题

Contents

一般 Library 问题

如何找到执行任务 X 的模块或应用程序?

检查Library 参考以查看是否有相关的标准库模块。 (finally,您将了解标准库中的内容,并且可以跳过此步骤.)

对于第三方程序包,请搜索Python 包索引或tryGoogle或其他 Web 搜索引擎。搜索“ Python”以及一个或两个与您感兴趣的主题相关的关键字通常会发现有帮助。

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

如果找不到模块的源文件,则它可能是以 C,C 或其他编译语言实现的内置或动态加载的模块。在这种情况下,您可能没有源文件,或者可能是mathmodule.c之类的东西,位于 C 源目录的某个位置(不在 Python 路径上)。

Python 中至少有三种模块:

  • 用 Python(.py)编写的模块;

  • 用 C 语言编写并动态加载的模块(.dll,.pyd,.so,.sl 等);

  • 用 C 编写并与解释器链接的模块;要获取这些列表,请键入:

import sys
print sys.builtin_module_names

如何在 Unix 上使 Python 脚本可执行?

您需要做两件事:脚本文件的模式必须是可执行的,第一行必须以#!开头,后跟 Python 解释器的路径。

首先pass执行chmod +x scriptfilechmod 755 scriptfile完成。

第二种方法可以pass多种方式完成。最直接的方法是写

#!/usr/local/bin/python

作为文件的第一行,使用平台上安装 Python 解释器的路径名。

如果您希望脚本独立于 Python 解释器所在的位置,则可以使用 env 程序。假设 Python 解释器位于用户 PATH的目录中,几乎所有的 Unix 变体都支持以下内容:

#!/usr/bin/env python

不要对 CGI 脚本执行此操作。 CGI 脚本的 PATH变量通常很小,因此您需要使用解释器的实际绝对路径名。

有时,用户环境太满了,以致 /usr/bin/env 程序失败;或根本没有 env 程序。在这种情况下,您可以try以下破解(由于 Alex Rezinsky):

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

较小的缺点是,它定义了脚本的__doc_字符串。但是,您可以pass添加

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

是否有适用于 Python 的 curses/termcap 软件包?

对于 Unix 变体,标准的 Python 源分发版在Modules子目录中带有 curses 模块,尽管默认情况下未编译该模块。 (请注意,这在 Windows 发行版中不可用– Windows 没有 curses 模块.)

curses模块支持基本 curses Function以及 ncurses 和 SYSV curses 的许多其他Function,例如颜色,备用字符集支持,填充和鼠标支持。这意味着该模块与仅具有 BSD curses 的 os 不兼容,但是目前似乎没有任何维护的 os 属于此类。

对于 Windows:使用consolelib 模块

Python 中是否有相当于 C 的 onexit()的代码?

atexit模块提供类似于 C 的onexit()的寄存器Function。

为什么我的 signal 处理程序不起作用?

最常见的问题是使用错误的参数列表语句 signal 处理程序。被称为

handler(signum, frame)

所以应该用两个参数语句它:

def handler(signum, frame):
    ...

Common tasks

如何测试 Python 程序或组件?

Python 带有两个测试框架。 doctest模块在模块的文档字符串中查找示例并运行它们,将输出与文档字符串中给出的预期输出进行比较。

unittest模块是一个模仿 Java 和 Smalltalk 测试框架的高级测试框架。

为了简化测试,您应该在程序中使用良好的模块化设计。您的程序应该将几乎所有Function封装在函数或类方法中–有时会产生令人惊讶和令人愉悦的效果,使程序运行更快(因为局部变量访问比全局访问快)。此外,程序应避免依赖于更改全局变量,因为这会使测试变得更加困难。

程序的“全局主逻辑”可能很简单

if __name__ == "__main__":
    main_logic()

在程序主模块的底部。

一旦您的程序被组织为Function和类行为的可收拾的集合,您就应该编写测试Function以测试行为。自动化测试序列的测试套件可以与每个模块关联。这听起来需要做很多工作,但是由于 Python 非常简洁灵活,因此非常容易。pass与“生产代码”并行编写测试函数,可以使编码更加令人愉悦和有趣,因为这样可以更容易地发现错误,甚至可以早期发现设计缺陷。

并非旨在作为程序主要模块的“支持模块”可以包括对该模块的自检。

if __name__ == "__main__":
    self_test()

当外部接口不可用时,即使使用复杂的外部接口进行交互的程序也可以pass使用 Python 中实现的“伪”接口进行测试。

如何从文档字符串创建文档?

pydoc模块可以从 Python 源代码中的文档字符串创建 HTML。纯粹从文档字符串创建 API 文档的替代方法是epydocSphinx还可以包含文档字符串内容。

如何一次获得一次按键?

对于 Unix 变体,有几种解决方案。使用 curses 做到这一点很简单,但是 curses 是一个需要学习的相当大的模块。这是一个没有 curses 的解决方案:

import termios, fcntl, sys, os
fd = sys.stdin.fileno()

oldterm = termios.tcgetattr(fd)
newattr = termios.tcgetattr(fd)
newattr[3] = newattr[3] & ~termios.ICANON & ~termios.ECHO
termios.tcsetattr(fd, termios.TCSANOW, newattr)

oldflags = fcntl.fcntl(fd, fcntl.F_GETFL)
fcntl.fcntl(fd, fcntl.F_SETFL, oldflags | os.O_NONBLOCK)

try:
    while 1:
        try:
            c = sys.stdin.read(1)
            print "Got character", repr(c)
        except IOError: pass
finally:
    termios.tcsetattr(fd, termios.TCSAFLUSH, oldterm)
    fcntl.fcntl(fd, fcntl.F_SETFL, oldflags)

您需要termiosfcntl模块才能使其正常工作,尽管在其他地方也可以使用,但我仅在 Linux 上进行过try。在此代码中,一次读取并打印一个字符。

termios.tcsetattr()关闭标准 Importing 的回显并禁用规范模式。 fcntl.fnctl()用于获取 stdin 的文件 Descriptors 标志并将其修改为非阻塞模式。由于读取标准 Importing 为空时会导致IOError,因此将捕获并忽略此错误。

Threads

如何使用线程编程?

确保使用threading模块而不是thread模块。 threading模块在thread模块提供的低级基元之上构建了方便的抽象。

Aahz 在其线程教程中提供了一组有用的幻灯片。参见http://www.pythoncraft.com/OSCON2001/

我的线程似乎都没有运行:为什么?

一旦主线程退出,所有线程都会被杀死。您的主线程运行太快,没有时间来做任何工作。

一个简单的解决方法是在程序末尾添加一个足以使所有线程完成的睡眠:

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) # <----------------------------!

但是现在(在许多平台上)线程不再并行运行,而是 Sequences 运行,一次运行一次!原因是 OS 线程调度程序在阻塞前一个线程之前不会启动新线程。

一个简单的解决方法是在 run 函数的开头添加一个小的睡眠:

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)

与其try猜测time.sleep()的延迟值,不如使用某种 signal 量机制。一种想法是使用Queue模块创建队列对象,让每个线程在完成时将一个令牌附加到队列中,并让主线程从队列中读取与线程数量一样多的令牌。

如何在许多工作线程中分配工作?

使用Queue模块创建包含作业列表的队列。 Queue类维护对象列表,并具有.put(obj)方法(将项目添加到队列中)和.get()方法以将其返回。该类将负责必要的锁定,以确保每个作业准确地分发一次。

这是一个简单的例子:

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.currentThread(),
            print 'queue empty'
            break
        else:
            print 'Worker', threading.currentThread(),
            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)

运行时,将产生以下输出:

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

有关更多详细信息,请查阅模块的文档。 Queue类提供了Function丰富的界面。

哪种全局值突变是线程安全的?

内部使用全局解释器锁(GIL)来确保一次仅一个线程在 Python VM 中运行。通常,Python 仅在字节码指令之间提供在线程之间切换的Function。可passsys.setcheckinterval()设置切换的频率。因此,从 Python 程序的角度来看,每个字节码指令以及因此从每个指令到达的所有 C 实现代码都是原子的。

从理论上讲,这意味着要进行精确的记帐就需要对 PVM 字节码的实现有充分的了解。实际上,这意味着对内置数据类型(整数,列表,字典等)的共享变量的操作实际上是“看起来原子的”。

例如,以下操作都是原子操作(L,L1,L2 是列表,D,D1,D2 是字典,x,y 是对象,i,j 是整数):

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()

These aren't:

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

当其他对象的引用计数达到零时,替换其他对象的操作可能会调用其他对象的del()方法,这可能会影响事物。对于字典和列表的大量更新尤其如此。如有疑问,请使用互斥锁!

我们不能摆脱全局翻译锁定吗?

全局解释器锁(GIL)通常被认为是在高端 multiprocessing 器服务器计算机上部署 Python 的障碍,因为坚持认为(几乎)所有 Python 代码只能在运行时运行,因此多线程 Python 程序实际上仅使用一个 CPU。举行了 GIL。

在 Python 1.5 时代,Greg Stein 实际上实现了一个全面的补丁集(“自由线程”补丁),该补丁集删除了 GIL,并用细粒度的锁定代替了它。不幸的是,即使在 Windows(锁非常有效)上,它运行普通 Python 代码的速度也比使用 GIL 的解释器慢两倍。在 Linux 上,由于 pthread 锁的效率不高,因此性能损失更为严重。

从那以后,摆脱 GIL 的想法偶尔会出现,但是没有人找到应对预期的速度下降的方法,如果代码的运行速度减半,则不使用线程的用户将不满意。 Greg 的免费线程补丁集尚未针对最新的 Python 版本保持最新。

这并不意味着您不能在多 CPU 机器上充分利用 Python!您只需要 Creating 性地将工作分成多个进程而不是多个线程即可。明智地使用 Cextensions 也将有所帮助;如果使用 Cextensions 执行耗时的任务,则该 extensions 可以在执行线程位于 C 代码中时释放 GIL,并允许其他线程完成某些工作。

有人建议,GIL 应该是每个解释器状态的锁,而不是 true 的全局锁。则解释器将无法共享对象。不幸的是,这也不可能发生。这将是一项巨大的工作,因为当前许多对象实现都具有全局状态。例如,小整数和短字符串被缓存;这些缓存将必须移至解释器状态。其他对象类型有其自己的空闲列表。这些空闲列表将必须移至解释器状态。等等。

而且我怀疑它是否可以在有限的时间内完成,因为第三方扩展存在相同的问题。第三方扩展的写入速度可能比您将其转换为将其所有全局状态存储在解释器状态时要快。

最后,一旦多个解释器不共享任何状态,在单独的过程中运行每个解释器会获得什么yield?

Importing 和输出

如何删除文件? (以及其他文件问题...)

使用os.remove(filename)os.unlink(filename);有关文档,请参见os模块。这两个Function是相同的。 unlink()只是此Function的 Unix 系统调用的名称。

要删除目录,请使用os.rmdir();使用os.mkdir()创建一个。 os.makedirs(path)将在path中创建任何不存在的中间目录。 os.removedirs(path)将删除中间目录,只要它们为空;如果要删除整个目录树及其内容,请使用shutil.rmtree()

要重命名文件,请使用os.rename(old_path, new_path)

要截断文件,请使用f = open(filename, "r+")打开它,然后使用f.truncate(offset);偏移量默认为当前搜索位置。用os.open()打开的文件也有os.ftruncate(fd, offset),其中* fd *是文件 Descriptors(一个小整数)。

shutil模块还包含用于处理文件的许多Function,包括copyfile()copytree()rmtree()

如何复制文件?

shutil模块包含copyfile()函数。请注意,在 MacOS 9 上,它不会复制资源派生和 Finder 信息。

如何读取(或写入)二进制数据?

要读取或写入复杂的二进制数据格式,最好使用struct模块。它允许您获取包含二进制数据(通常是数字)的字符串,并将其转换为 Python 对象。反之亦然。

例如,以下代码从文件中读取两个 2 字节整数和一个 4 字节大端格式的整数:

import struct

f = open(filename, "rb")  # Open in binary mode for portability
s = f.read(8)
x, y, z = struct.unpack(">hhl", s)

格式字符串中的'>'强制使用大端数据。字母“ h”从字符串中读取一个“短整数”(2 字节),“ l”从字符串中读取一个“长整数”(4 字节)。

对于更常规的数据(例如,整数或浮点数的同类列表),您还可以使用array模块。

我似乎无法在使用 os.popen()创建的管道上使用 os.read();为什么?

os.read()是一个低级函数,它带有文件 Descriptors,这是一个小的整数,表示打开的文件。 os.popen()创建一个高级文件对象,其类型与内置open()函数返回的类型相同。因此,要从使用os.popen()创建的管道* p 中读取 n *个字节,您需要使用p.read(n)

如何使用连接到 Importing 和输出的管道来运行子流程?

使用popen2模块。例如:

import popen2
fromchild, tochild = popen2.popen2("command")
tochild.write("input\n")
tochild.flush()
output = fromchild.readline()

警告:通常这样做是不明智的,因为您很容易造成死锁,在该死锁中您的进程被阻塞,await 孩子的输出,而孩子被阻塞,await 您的 Importing。这可能是由于父级期望子级输出比其输出更多的文本,或者是由于缺乏刷新而使数据滞留在 stdio 缓冲区中。 Python 父级当然可以在读取任何输出之前显式刷新它发送给子级的数据,但是如果子级是幼稚的 C 程序,则可能已经编写成永远不会显式刷新其输出,即使它是交互式的,因为刷新通常是自动的。

请注意,如果您使用popen3()读取 stdout 和 stderr,则也可能出现死锁。如果两者之Pair于内部缓冲区太大(增大缓冲区大小无济于事),并且您先read()另一个缓冲区,则也会出现死锁。

注意 popen2 中的错误:除非您的程序调用wait()waitpid(),否则永远不会删除完成的子进程,并且由于子进程数量的限制,finally对 popen2 的调用将失败。使用os.WNOHANG选项调用os.waitpid()可以防止这种情况;插入此类调用的好地方是在再次调用popen2之前。

在许多情况下,您 true 需要的只是pass命令运行一些数据并返回结果。除非数据量很大,否则最简单的方法是将其写入临时文件,然后以该临时文件作为 Importing 运行命令。标准模块tempfile导出mktemp()函数以生成唯一的临时文件名。

import tempfile
import os

class Popen3:
    """
    This is a deadlock-safe version of popen that returns
    an object with errorlevel, out (a string) and err (a string).
    (capturestderr may not work under windows.)
    Example: print Popen3('grep spam','\n\nhere spam\n\n').out
    """
    def __init__(self,command,input=None,capturestderr=None):
        outfile=tempfile.mktemp()
        command="( %s ) > %s" % (command,outfile)
        if input:
            infile=tempfile.mktemp()
            open(infile,"w").write(input)
            command=command+" <"+infile
        if capturestderr:
            errfile=tempfile.mktemp()
            command=command+" 2>"+errfile
        self.errorlevel=os.system(command) >> 8
        self.out=open(outfile,"r").read()
        os.remove(outfile)
        if input:
            os.remove(infile)
        if capturestderr:
            self.err=open(errfile,"r").read()
            os.remove(errfile)

请注意,许多交互式程序(例如 vi)在用管道代替标准 Importing 和输出时效果不佳。您将必须使用伪 ttys(“ ptys”)代替管道。或者,您可以使用 Python 接口访问 Don Libes 的“ expect”库。符合预期的 Pythonextensions 为“ expy”,可从http://expectpy.sourceforge.net获得。像预期的一样工作的纯 Python 解决方案是pexpect

如何访问串行(RS232)端口?

对于 Win32,POSIX(Linux,BSD 等),Jython:

对于 Unix,请参见 Mitch Chapman 的 Usenet post:

为什么不关闭 sys.stdout(stdin,stderr)却真的将其关闭?

Python 文件对象是 C 流之上的高层抽象层,而 C 流又是(除其他事项之外)低级 C 文件 Descriptors 之上的中层抽象层。

对于您pass内置的file构造函数在 Python 中创建的大多数文件对象,f.close()将 Python 文件对象从 Python 的角度标记为已关闭,并且还安排了关闭基础 C 流。当f变成垃圾时,这也会在f的析构函数中自动发生。

但是 st,stdout 和 stderr 被 Python 特殊对待,因为 C 也赋予它们特殊的状态。运行sys.stdout.close()会将 Python 级别的文件对象标记为已关闭,但不会关闭相关的 C 流。

要关闭这三者之一的基础 C 流,首先应确保这是您 true 想要做的(例如,您可能会混淆try执行 I/O 的扩展模块)。如果是,请使用 os.close:

os.close(0)   # close C's stdin stream
os.close(1)   # close C's stdout stream
os.close(2)   # close C's stderr stream

Network/Internet Programming

有哪些适用于 Python 的 WWW 工具?

请参见《Library 参考手册》中标题为互联网协议和支持互联网数据处理的章节。 Python 有许多模块,可帮助您构建服务器端和 Client 端 Web 系统。

Paul Boddie 在https://wiki.python.org/moin/WebProgramming维护可用框架的摘要。

Cameron Laird 在http://phaseit.net/claird/comp.lang.python/web_python上维护了一组有用的有关 Python Web 技术的页面。

如何模仿 CGI 表单提交(METHOD = POST)?

我想检索张贴表单的结果的网页。是否有现有的代码可以让我轻松地做到这一点?

是。这是一个使用 httplib 的简单示例:

#!/usr/local/bin/python

import httplib, sys, time

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

# connect and send the server a path
httpobj = httplib.HTTP('www.some-server.out-there', 80)
httpobj.putrequest('POST', '/cgi-bin/some-cgi-script')
# now generate the rest of the HTTP headers...
httpobj.putheader('Accept', '*/*')
httpobj.putheader('Connection', 'Keep-Alive')
httpobj.putheader('Content-type', 'application/x-www-form-urlencoded')
httpobj.putheader('Content-length', '%d' % len(qs))
httpobj.endheaders()
httpobj.send(qs)
# find out what the server said in response...
reply, msg, hdrs = httpobj.getreply()
if reply != 200:
    sys.stdout.write(httpobj.getfile().read())

请注意,通常对于百分比编码的 POST 操作,查询字符串必须使用urllib.urlencode()引起来。例如,发送name=Guy Steele, Jr.

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

我应该使用哪个模块来帮助生成 HTML?

您可以在Web 编程 Wiki 页面上找到有用链接的集合。

如何从 Python 脚本发送邮件?

使用标准库模块smtplib

这是一个使用它的非常简单的交互式邮件发件人。此方法将在任何支持 SMTP 侦听器的主机上工作。

import sys, smtplib

fromaddr = raw_input("From: ")
toaddrs  = raw_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 程序的位置在系统之间有所不同。有时是/usr/lib/sendmail,有时是/usr/sbin/sendmail。 sendmail 手册页将为您提供帮助。这是一些示例代码:

import os

SENDMAIL = "/usr/sbin/sendmail"  # sendmail location
p = os.popen("%s -t -i" % SENDMAIL, "w")
p.write("To: [email protected]\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

如何避免阻塞套接字的 connect()方法?

选择模块通常用于帮助套接字上的异步 I/O。

为了防止 TCP 连接阻塞,可以将套接字设置为非阻塞模式。然后,当您执行connect()时,要么立即连接(不太可能),要么获得包含错误号.errno的异常。 errno.EINPROGRESS表示连接正在进行中,但尚未完成。不同的 os 将返回不同的值,因此您将必须检查系统返回的内容。

您可以使用connect_ex()方法来避免创建异常。它只会返回 errno 值。要进行轮询,您可以稍后再调用connect_ex() – 0 或errno.EISCONN表示您已连接–或可以pass此套接字选择以检查其是否可写。

Databases

Python 中是否有任何数据库包接口?

Yes.

Python 2.3 包含bsddb软件包,该软件包提供了与 BerkeleyDB 库的接口。标准 Python 也包含指向基于磁盘的哈希的接口,例如DBMGDBM

支持大多数关系数据库。有关详情,请参见DatabaseProgramming Wiki 页面

如何在 Python 中实现持久对象?

pickle库模块以非常通用的方式解决了这个问题(尽管您仍然无法存储打开的文件,套接字或窗口之类的东西),而shelve库模块使用 pickle 和(g)dbm 创建包含任意 Python 对象的持久 Map。为了获得更好的性能,可以使用cPickle模块。

做事更尴尬的是用 pickle 的小妹妹,marshal。 marshal模块提供了非常快速的方法来将非圆形基本 Python 类型存储到文件和字符串中,然后再存储回来。尽管封送处理Function并不能完成诸如存储实例之类的事情,也不能正确处理共享引用,但运行速度却非常快。例如,加载半兆字节的数据可能花费不到三分之一的时间。这通常比做更复杂和通用的事情要好,例如将 gdbm 与 pickle/shelf 一起使用。

为什么 cPickle 这么慢?

默认情况下,pickle使用相对较旧且较慢的格式以实现向后兼容。但是,您可以指定其他更快的协议版本:

largeString = 'z' * (100 * 1024)
myPickle = cPickle.dumps(largeString, protocol=1)

如果在打开 bsddb(或 anydbm)数据库的情况下我的程序崩溃了,则它会损坏。怎么会?

必须使用数据库的.close()方法显式关闭使用 bsddb 模块打开的数据库(并且通常pass anydbm 模块打开,因为它会优先使用 bsddb),以进行写访问。基础库缓存需要转换为磁盘形式并写入的数据库内容。

如果您已经初始化了一个新的 bsddb 数据库,但在程序崩溃前未对其进行任何写入操作,则通常会出现一个零长度的文件,并在下次打开该文件时遇到异常。

我试图打开 Berkeley DB 文件,但是 bsddb 产生了 bsddb.error:(22,“无效参数”)。救命!如何恢复我的数据?

不要惊慌!您的数据可能是完整的。导致此错误的最常见原因是您try使用更高版本的 Berkeley DB 库打开一个早期的 Berkeley DB 文件。

现在,许多 Linux 系统都提供了所有三个版本的 Berkeley DB。如果要从版本 1 迁移到较新的版本,请使用 db_dump185 转储数据库的纯文本版本。如果要从版本 2 迁移到版本 3,请使用 db2_dump 创建数据库的纯文本版本。在这两种情况下,都可以使用 db_load 为计算机上安装的最新版本创建新的本机数据库。如果已安装 Berkeley DB 的版本 3,则应该能够使用 db2_load 创建本机版本 2 数据库。

您应该远离 Berkeley DB 版本 1 文件,因为哈希文件代码包含可能损坏数据的已知错误。

math 与数值

如何在 Python 中生成随机数?

标准模块random实现了一个随机数生成器。用法很简单:

import random
random.random()

这将返回范围为[0,1)的随机浮点数。

此模块中还有许多其他专用生成器,例如:

  • randrange(a, b)选择[a,b)范围内的整数。

  • uniform(a, b)在[a,b)范围内选择一个浮点数。

  • normalvariate(mean, sdev)对正态(高斯)分布进行采样。

一些更高级别的函数直接对序列进行操作,例如:

  • choice(S)从给定序列中选择随机元素

  • shuffle(L)就地随机整理列表,即随机排列

您还可以实例化一个Random类来创建独立的多个随机数生成器。