文章目录
libs和扩展FAQ
我如何在Python中生成随机数字?
Python中是否有任何数据库包的接口?
你如何在Python中实现持久化对象?
为什么cPickle这么慢?
如果我的程序崩溃,打开一个bsddb(或anydbm)数据库,它会被损坏。怎么来的?
我试图打开Berkeley DB文件,但bsddb产生bsddb.error:(22,'无效参数')。帮帮我!我怎样才能恢复我的数据?
Python有什么WWW工具?
我如何模仿CGI表单提交(METHOD = POST)?
我应该使用什么模块来帮助生成HTML?
我如何从Python脚本发送邮件?
如何避免在套接字的connect()方法中阻塞?
我如何删除文件?(和其他文件问题...)
我如何复制文件?
如何读取(或写入)二进制数据?
我似乎无法使用os.popen()创建的管道上使用os.read(); 为什么?
如何运行管道连接到输入和输出的子进程?
我如何访问串行(RS232)端口?
为什么不关闭sys.stdout(stdin,stderr)真的关闭它?
我如何使用线程编程?
我的线索似乎没有运行:为什么?
我如何在一堆工作线程中打包工作?
什么样的全球价值变异是线程安全的?
我们不能摆脱全球解释器锁吗?
我如何测试Python程序或组件?
如何从文档字符串创建文档?
我怎样一次获得一个按键?
我如何找到一个模块或应用程序来执行任务X?
math.py(socket.py,regex.py等)源文件在哪里?
我如何在Unix上创建一个Python脚本可执行文件?
是否有Python的curses / termcap包?
在Python中是否有和C的onexit()等价的东西?
为什么我的信号处理程序不工作?
一般图书馆问题
常见任务
主题
输入和输出
网络/互联网编程
数据库
数学和数字
一般lib库问题
我如何找到一个模块或应用程序来执行任务X?
检查库参考以查看是否有相关的标准库模块。(最终你会了解标准库中的内容,并且可以跳过这一步。)
对于第三方软件包,请搜索Python软件包索引或尝试使用Google或其他网络搜索引擎。搜索“Python”加上一两个关键字的关键词通常会找到一些有用的东西。
math.py(socket.py,regex.py等)源文件在哪里?
如果您找不到某个模块的源文件,它可能是以C,C ++或其他编译语言实现的内置或动态加载的模块。在这种情况下,您可能没有源文件,或者它可能类似于 mathmodule.c
C源代码目录中的某处(不在Python路径中)。
Python中至少有三种模块:
以Python(.py)编写的模块;
以C语言编写并动态加载的模块(.dll,.pyd,.so,.sl等);
以C语言编写并与口译员联系的模块; 要获得这些列表,请键入:
import sysprint sys.builtin_module_names
我如何在Unix上创建一个Python脚本可执行文件?
您需要做两件事:脚本文件的模式必须是可执行的,第一行必须以#!
Python解释器的路径开头。
第一个是通过执行或可能。chmod +x scriptfile
chmod 755 scriptfile
第二个可以通过多种方式完成。最直接的方法是写
#!/usr/local/bin/python
作为文件的第一行,在您的平台上使用Python解释器安装位置的路径名。
如果您希望脚本独立于Python解释器所在的位置,则可以使用env程序。几乎所有的Unix变体都支持以下内容,假设Python解释器位于用户的目录中 PATH
:
#!/usr/bin/env python
不要为CGI脚本执行此操作。该PATH
CGI脚本的变量通常非常小,因此您需要使用解释器的实际绝对路径名。
有时候,用户的环境太满了,以致/ usr / bin / env 程序失败; 或者根本没有env计划。在这种情况下,你可以尝试下面的黑客(由于Alex Rezinsky):
#! /bin/sh""":"exec python $0 ${1+"$@"}"""
小小的缺点是它定义了脚本的__doc__字符串。但是,您可以通过添加来修复该问题
__doc__ = """...Whatever..."""
是否有Python的curses / termcap包?
对于Unix变体,标准Python源代码发行在模块子目录中带有一个curses模块,尽管它并未默认编译。(请注意,这在Windows发行版中不可用 - Windows没有curses模块。)
该curses
模块支持基本的curses功能以及来自ncurses和SYSV curses的许多附加功能,如颜色,替代字符集支持,打击垫和鼠标支持。这意味着该模块与只有BSD诅咒的操作系统不兼容,但似乎没有任何属于此类别的当前维护的操作系统。
对于Windows:使用consolelib模块。
在Python中是否有和C的onexit()等价的东西?
该atexit
模块提供了一个类似于C的寄存器功能 onexit()
。
为什么我的信号处理程序不工作?
最常见的问题是信号处理程序是用错误的参数列表声明的。它被称为
handler(signum, frame)
所以应该用两个参数声明:
def handler(signum, frame): ...
常见任务
我如何测试Python程序或组件?
Python带有两个测试框架。该doctest
模块在模块的文档字符串中找到示例并运行它们,将输出与文档字符串中给出的预期输出进行比较。
该unittest
模块是一个基于Java和Smalltalk测试框架的发烧友测试框架。
为了使测试更容易,您应该在程序中使用良好的模块化设计。你的程序几乎应该具有封装在函数或类方法中的所有功能 - 而且这有时会让程序运行得更快(因为局部变量访问比全局访问更快),这有令人惊讶和令人愉快的效果。此外,程序应该避免依赖变异的全局变量,因为这使得测试更加困难。
你的程序的“全局主逻辑”可能就像
if __name__ == "__main__": main_logic()
在程序主模块的底部。
一旦你的程序被组织为一个易处理的函数和类行为集合,你应该编写测试函数来行使这些行为。可以将一系列测试自动化的测试套件与每个模块相关联。这听起来像很多工作,但由于Python非常简洁灵活,所以它非常简单。通过将测试函数与“生产代码”并行编写,您可以使编码变得更愉快和更有趣,因为这样可以更容易地发现错误,甚至更早地设计缺陷。
不打算成为程序主模块的“支持模块”可能包括模块的自检。
if __name__ == "__main__": self_test()
即使通过使用Python中实现的“假”接口,当外部接口不可用时,甚至可以测试与复杂外部接口交互的程序。
如何从文档字符串创建文档?
该pydoc
模块可以从您的Python源代码中的文档字符串创建HTML。纯粹从docstrings创建API文档的替代方法是epydoc。 狮身人面像还可以包含文档字符串内容。
我怎样一次获得一个按键?
对于Unix变体,有几种解决方案。使用curses来做这件事很简单,但curses是一个相当大的模块来学习。这是一个没有诅咒的解决方案:
import termios, fcntl, sys, osfd = sys.stdin.fileno()oldterm = termios.tcgetattr(fd)newattr = termios.tcgetattr(fd)newattr[3] = newattr[3] & ~termios.ICANON & ~termios.ECHOtermios.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: passfinally: termios.tcsetattr(fd, termios.TCSAFLUSH, oldterm) fcntl.fcntl(fd, fcntl.F_SETFL, oldflags)
你需要这个termios
和这个fcntl
模块才能工作,我只在Linux上试过,尽管它可以在其他地方工作。在此代码中,一次读取和打印一个字符。
termios.tcsetattr()
关闭stdin的回显并禁用规范模式。 fcntl.fnctl()
用于获取stdin的文件描述符标志并将其修改为非阻止模式。由于读取标准输入时,它是空的结果是 IOError
,这个错误被捕获并被忽略。
线程
我如何使用线程编程?
一定要使用threading
模块而不是thread
模块。该threading
模块在thread
模块提供的低级基元之上构建方便的抽象。
Aahz从他的线程教程中获得了一些有用的幻灯片,请参阅 http://www.pythoncraft.com/OSCON2001/。
我的线索似乎没有运行:为什么?
一旦主线程退出,所有线程都会被终止。你的主线程运行得太快,给线程没时间做任何工作。
一个简单的解决方法是在程序结束时添加一段睡眠时间,以便所有线程完成足够长的时间:
import threading, timedef thread_task(name, n): for i in range(n): print name, ifor i in range(10): T = threading.Thread(target=thread_task, args=(str(i), i)) T.start()time.sleep(10) # <----------------------------!
但现在(在许多平台上)线程并不是平行运行,而是按顺序运行,每次只运行一个线程!原因是OS线程调度程序在上一个线程被阻塞之前不会启动新线程。
一个简单的解决方法是在运行函数的开始处添加一个微小的睡眠:
def thread_task(name, n): time.sleep(0.001) # <---------------------! for i in range(n): print name, ifor i in range(10): T = threading.Thread(target=thread_task, args=(str(i), i)) T.start()time.sleep(10)
与其试图猜测一个好的延迟值time.sleep()
,最好是使用某种信号量机制。一个想法是使用该 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 queueq = Queue.Queue()# Start a pool of 5 workersfor i in range(5): t = threading.Thread(target=worker, name='worker %i' % (i+1)) t.start()# Begin adding work to the queuefor i in range(50): q.put(i)# Give threads time to runprint '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
课程提供了一个有特色的界面。
什么样的全球价值变异是线程安全的?
一个全局解释锁(GIL)在内部使用,以确保只有一个线程在Python虚拟机在运行时间。通常,Python提供仅在字节码指令之间在线程之间切换; 它的切换频率可以通过设置sys.setcheckinterval()
。因此,从Python程序的角度来看,每个字节码指令以及从每条指令到达的所有C实现代码都是原子。
从理论上讲,这意味着一个确切的会计需要精确理解PVM字节码的实现。实际上,这意味着对“看起来像原子”的内置数据类型(ints,lists,dicts等)的共享变量的操作确实是这样。
例如,以下操作都是原子的(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] = L2L.sort()x = yx.field = yD[x] = yD1.update(D2)D.keys()
这些不是:
i = i+1L.append(L[-1])L[i] = L[j]D[x] = D[x] + 1
__del__()
当引用计数达到零时,替换其他对象的操作可能会调用那些其他对象的 方法,这可能会影响事物。对于词典和列表的大量更新尤其如此。如有疑问,请使用互斥体!
我们不能摆脱全球解释器锁吗?
在全局解释锁(GIL)往往被视为一个障碍Python的高端多处理器服务器计算机的部署,因为一个多线程的Python程序有效地只使用一个CPU,由于坚持认为(几乎)所有的Python代码只能在GIL举行时运行。
在Python 1.5的时代,Greg Stein实际上实现了一个全面的补丁集(“免费线程”补丁),它们删除了GIL,并用细粒度锁定代替它。不幸的是,即使在Windows上(锁定效率非常高),这个运行普通Python代码的速度比使用GIL的解释器慢两倍。在Linux上,性能损失更加严重,因为pthread锁定效率不高。
从那时起,摆脱GIL的想法偶尔会出现,但没有人找到解决预期放缓的方法,而不使用线程的用户如果他们的代码以一半的速度运行就不会很高兴。格雷格的免费线程补丁集还没有保持最新的Python版本。
这并不意味着你不能在多CPU机器上很好地使用Python!你只需要在多个进程而不是多个线程之间进行创新 。明智地使用C扩展也将有所帮助; 如果您使用C扩展来执行耗时的任务,那么扩展可以释放GIL,而执行的线程位于C代码中,并允许其他线程完成一些工作。
有人认为,GIL应该是一个每个解释者国家的锁而不是真正的全球性锁; 口译员将无法共享对象。不幸的是,这也不可能发生。这将是一项巨大的工作,因为许多对象实现目前具有全局状态。例如,小的整数和短的字符串被缓存; 这些缓存将不得不转移到解释器状态。其他对象类型有自己的空闲列表; 这些免费名单将不得不转移到口译员的状态。等等。
我怀疑它甚至可以在有限的时间内完成,因为第三方扩展存在同样的问题。很可能第三方扩展的写入速度比将其转换为将其全部状态存储在解释器状态中的速度更快。
最后,一旦你有多个口译员没有分享任何状态,你在单独的过程中运行每个口译员所获得的成果是什么?
输入和输出
我如何删除文件?(和其他文件问题...)
使用os.remove(filename)
或os.unlink(filename)
; 有关文档,请参阅os
模块。这两个功能是相同的; unlink()
只是这个函数的Unix系统调用的名称。
要删除目录,请使用os.rmdir()
; 使用os.mkdir()
来创建一个。 os.makedirs(path)
将创建任何path
不存在的中间目录。os.removedirs(path)
只要它们是空的,就会删除中间目录; 如果要删除整个目录树及其内容,请使用shutil.rmtree()
。
要重命名文件,请使用。os.rename(old_path, new_path)
截断文件,使用打开它并使用 ; 偏移量默认为当前搜索位置。还有用于打开的文件,其中 fd是文件描述符(一个小整数)。f = open(filename, "r+")
f.truncate(offset)
os.ftruncate(fd,offset)
os.open()
该shutil
模块还包含了一些功能上的文件,包括工作copyfile()
,copytree()
和 rmtree()
。
我如何复制文件?
该shutil
模块包含一个copyfile()
功能。请注意,在MacOS 9上,它不会复制资源分支和Finder信息。
如何读取(或写入)二进制数据?
要读取或写入复杂的二进制数据格式,最好使用该struct
模块。它允许你获取一个包含二进制数据(通常是数字)的字符串并将其转换为Python对象; 反之亦然。
例如,下面的代码从文件中读取两个2字节整数和一个大端格式的4字节整数:
import structf = open(filename, "rb") # Open in binary mode for portabilitys = f.read(8)x, y, z = struct.unpack(">hhl", s)
格式字符串中的'>'强制大端数据; 字母'h'读取一个“短整数”(2个字节),'l'从字符串中读取一个“长整数”(4个字节)。
对于更规则的数据(例如,整数或浮点数的同类列表),您也可以使用该array
模块。
我似乎无法使用os.popen()创建的管道上使用os.read(); 为什么?
os.read()
是一个低级函数,它接受一个文件描述符,一个代表打开文件的小整数。 os.popen()
创建一个高级文件对象,内置open()
函数返回的是相同的类型。因此,要从创建的管道p读取n个字节,您需要使用。os.popen()
p.read(n)
如何运行管道连接到输入和输出的子进程?
使用该popen2
模块。例如:
import popen2fromchild, tochild = popen2.popen2("command")tochild.write("input\n")tochild.flush()output = fromchild.readline()
警告:一般来说,这样做是不明智的,因为当孩子被阻止等待你的输入时,你可以很容易地导致你的进程被阻塞的地方等待孩子输出的死锁。这可能是由于父母期望孩子输出的文本比它更多,或者由于没有刷新而导致数据卡在stdio缓冲区中。Python父级当然可以在它读取任何输出之前显式地清除它发送给子级的数据,但是如果子级是一个幼稚的C程序,它可能已被写入从不显式刷新其输出,即使它是交互式的,因为冲刷通常是自动的。
请注意,如果您用于popen3()
读取标准输出和标准错误,则也可能发生死锁。如果其中一个对于内部缓冲区来说太大(增加缓冲区的大小并没有帮助),read()
而另一个首先出现,则也会出现死锁。
注意popen2中的错误:除非程序调用wait()
或waitpid()
完成的子进程永远不会被删除,并且由于子进程的数量限制,最终对popen2的调用将失败。os.waitpid()
使用该os.WNOHANG
选项调用 可以防止这种情况; 在popen2
再次打电话之前,插入这样一个电话的好地方是。
在许多情况下,您真正需要的是通过命令运行一些数据并将结果返回。除非数据量非常大,否则最简单的方法是将其写入临时文件并使用该临时文件作为输入运行命令。标准模块tempfile
导出一个 mktemp()
函数来生成唯一的临时文件名。
import tempfileimport osclass 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)不能很好地用管道代替标准输入和输出。您将不得不使用伪ttys(“ptys”)而不是管道。或者你可以使用一个Python接口来Don Libes的“expect”库。一个可以接口的Python扩展称为“expy”,可从http://expectpy.sourceforge.net获得。像预期一样工作的纯Python解决方案就是一个好的方面。
我如何访问串行(RS232)端口?
对于Win32,POSIX(Linux,BSD等),Jython:
http://pyserial.sourceforge.net
对于Unix,请参阅Mitch Chapman的Usenet帖子:
https://groups.google.com/groups?selm=34A04430.CF9@ohioee.com
为什么不关闭sys.stdout(stdin,stderr)真的关闭它?
Python文件对象是C流顶层的一个高层抽象层,它反过来是低层C文件描述符之上的一个中等抽象层。
对于通过内置file
构造函数在Python中创建的大多数文件对象,f.close()
将Python文件对象标记为从Python的角度关闭,并且还安排关闭底层的C流。这也会在f
析构函数中自动发生,当它f
变成垃圾时。
但是,标准输入,输出和错误是由Python的特殊处理,因为特殊的身份也由C.运行给他们sys.stdout.close()
标记了Python级别的文件对象被关闭,但并没有关闭关联的C流。
要关闭其中一个三层的底层C流,首先应确定这就是您真正想要做的事情(例如,您可能会混淆扩展模块尝试执行I / O操作)。如果是,请使用os.close:
os.close(0) # close C's stdin streamos.close(1) # close C's stdout streamos.close(2) # close C's stderr stream
网络/ Internet编程
Python有什么WWW工具?
请参阅“ 库参考手册”中标题为“ Internet协议和支持”和“ Internet数据处理”的章节。Python有很多模块可以帮助你构建服务器端和客户端的Web系统。
Paul Boddie在https://wiki.python.org/moin/WebProgramming上维护了可用框架的摘要 。
Cameron Laird在http://phaseit.net/claird/comp.lang.python/web_python上维护一组有关Python网络技术的有用网页 。
我如何模仿CGI表单提交(METHOD = POST)?
我想检索作为发布表单结果的网页。有没有现成的代码可以让我轻松做到这一点?
是。以下是一个使用httplib的简单示例:
#!/usr/local/bin/pythonimport httplib, sys, time# build the query stringqs = "First=Josephine&MI=Q&Last=Public"# connect and send the server a pathhttpobj = 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 Programming wiki页面上找到有用链接的集合。
我如何从Python脚本发送邮件?
使用标准库模块smtplib
。
这是一个使用它的非常简单的交互式邮件发件人。这种方法适用于任何支持SMTP侦听器的主机。
import sys, smtplibfromaddr = 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 sendserver = smtplib.SMTP('localhost')server.sendmail(fromaddr, toaddrs, msg)server.quit()
只有Unix的选择使用sendmail。sendmail程序的位置因系统而异; 有时候/usr/lib/sendmail
,有时候是这样 /usr/sbin/sendmail
。sendmail手册页将帮助你。以下是一些示例代码:
import osSENDMAIL = "/usr/sbin/sendmail" # sendmail locationp = 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 bodyp.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
表示连接正在进行中,但尚未完成。不同的操作系统将返回不同的值,所以你将不得不检查系统上返回的内容。
您可以使用该connect_ex()
方法避免创建异常。它只会返回错误值。要进行轮询,您可以connect_ex()
稍后再调用- 0或errno.EISCONN
指示您已连接 - 或者您可以传递此套接字以选择是否可写。
数据库
Python中是否有任何数据库包的接口?
是。
Python 2.3包含bsddb
提供BerkeleyDB库接口的包。接口的基于磁盘的散列如DBM
和GDBM
中还包含标准Python。
支持大多数关系数据库可用。有关详细信息,请参阅 DatabaseProgramming wiki页面。
你如何在Python中实现持久化对象?
该pickle
库模块来解决这个非常普遍的方式(虽然你仍然不能存放东西像打开的文件,套接字或窗口),和 shelve
库模块使用泡菜和(g)DBM创建一个包含任意Python对象持久化映射。为了获得更好的性能,您可以使用该cPickle
模块。
一个更尴尬的做法是用泡菜的小妹妹元帅。该marshal
模块提供了非常快速的方法来将非圆形的基本Python类型存储到文件和字符串中,然后再返回。虽然编组不会做像商店实例或正确处理共享引用的花哨事物,但确实运行得非常快。例如,加载一个半兆字节的数据可能不到三分之一秒。这经常会让更复杂和更普遍的事情发生,比如在pickle / shelve中使用gdbm。
为什么cPickle这么慢?
默认情况下pickle
使用相对较旧和较慢的格式以实现向后兼容。但是,您可以指定更快的其他协议版本:
largeString = 'z' * (100 * 1024)myPickle = cPickle.dumps(largeString, protocol=1)
如果我的程序在打开bsddb(或anydbm)数据库时崩溃,它会被破坏。怎么来的?
使用bsddb模块打开数据库(通常由anydbm模块打开,因为它将优先使用bsddb)必须使用.close()
数据库的方法显式关闭。底层库缓存需要转换为磁盘形式并写入的数据库内容。
如果您在程序崩溃之前初始化了一个新的bsddb数据库但没有写入任何内容,那么您通常会得到一个零长度的文件,并在下次打开该文件时遇到异常。
我试图打开Berkeley DB文件,但是bsddb产生bsddb.error:(22,'无效参数')。帮帮我!我怎样才能恢复我的数据?
不要惊慌!您的数据可能完好无损。导致错误的最常见原因是您试图使用较新版本的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文件,因为散列文件代码包含可能破坏数据的已知错误。
数学和数字
我如何在Python中生成随机数字?
标准模块random
实现一个随机数发生器。用法很简单:
import randomrandom.random()
这会返回[0,1)范围内的随机浮点数。
此模块中还有许多其他专用发生器,例如:
randrange(a, b)
在[a,b)范围内选择一个整数。uniform(a, b)
在[a,b)范围内选择一个浮点数。normalvariate(mean, sdev)
采样法线(高斯)分布。
一些高级函数直接对序列进行操作,例如:
choice(S)
从给定的序列中选择随机元素shuffle(L)
在原地洗牌,即随机排列
还有一个Random
类可以实例化来创建独立的多个随机数生成器。