接 Python Tutorial中英双语对照文档3
CHAPTER
ELEVEN
This second tour covers more advanced modules that support professional programming needs. These modules rarely occur in small scripts.
第二部分包含了更高级的模块, 它们支持专业的程序需求. 这些模块很少出现在小脚本里.
The reprlib module provides a version of repr() customized for abbreviated displays of large or deeply nested containers:
>>> import reprlib
>>> reprlib.repr(set('supercalifragilisticexpialidocious'))
"{'a', 'c', 'd', 'e', 'f', 'g', ...}"
reprlib 模块提供了为大或深的嵌套容器去简单地显示定制的 repr() 版本:
>>> import reprlib
>>> reprlib.repr(set('supercalifragilisticexpialidocious'))
"{'a', 'c', 'd', 'e', 'f', 'g', ...}"
The pprint module offers more sophisticated control over printing both built-in and user defined objects in a way that is readable by the interpreter. When the result is longer than one line, the “pretty printer” adds line breaks and indentation to more clearly reveal data structure:
>>> import pprint
>>> t = [[[['black', 'cyan'], 'white', ['green', 'red']], [['magenta',
... 'yellow'], 'blue']]]
...
>>> pprint.pprint(t, width=30)
[[[['black', 'cyan'],
'white',
['green', 'red']],
[['magenta', 'yellow'],
'blue']]]
pprint 模块提供更复杂的控制, 以便以解释器可读的方式打印内置和用户定义的对象. 当结果超过一行时, “美化打印(pretty printer)” 添加断行和缩进去更清楚地显示数据结构:
>>> import pprint
>>> t = [[[['black', 'cyan'], 'white', ['green', 'red']], [['magenta',
... 'yellow'], 'blue']]]
...
>>> pprint.pprint(t, width=30)
[[[['black', 'cyan'],
'white',
['green', 'red']],
[['magenta', 'yellow'],
'blue']]]
The textwrap module formats paragraphs of text to fit a given screen width:
>>> import textwrap
>>> doc = """The wrap() method is just like fill() except that it returns
... a list of strings instead of one big string with newlines to separate
... the wrapped lines."""
...
>>> print(textwrap.fill(doc, width=40))
The wrap() method is just like fill()
except that it returns a list of strings
instead of one big string with newlines
to separate the wrapped lines.
textwrap 模块格式化文本段落去适应给定的屏幕宽度:
>>> import textwrap
>>> doc = """The wrap() method is just like fill() except that it returns
... a list of strings instead of one big string with newlines to separate
... the wrapped lines."""
...
>>> print(textwrap.fill(doc, width=40))
The wrap() method is just like fill()
except that it returns a list of strings
instead of one big string with newlines
to separate the wrapped lines.
The locale module accesses a database of culture specific data formats. The grouping attribute of locale’s format function provides a direct way of formatting numbers with group separators:
>>> import locale
>>> locale.setlocale(locale.LC_ALL, 'English_United States.1252')
'English_United States.1252'
>>> conv = locale.localeconv() # get a mapping of conventions
>>> x = 1234567.8
>>> locale.format("%d", x, grouping=True)
'1,234,567'
>>> locale.format_string("%s%.*f", (conv['currency_symbol'],
... conv['frac_digits'], x), grouping=True)
'$1,234,567.80'
locale(语言环境) 模块接驳文化特定数据格式的数据库. 语言环境格式函数的分组属性提供了使用组分隔符格式化数字的直接方法:
>>> import locale
>>> locale.setlocale(locale.LC_ALL, 'English_United States.1252')
'English_United States.1252'
>>> conv = locale.localeconv() # get a mapping of conventions
>>> x = 1234567.8
>>> locale.format("%d", x, grouping=True)
'1,234,567'
>>> locale.format_string("%s%.*f", (conv['currency_symbol'],
... conv['frac_digits'], x), grouping=True)
'$1,234,567.80'
The string module includes a versatile Template class with a simplified syntax suitable for editing by end-users. This allows users to customize their applications without having to alter the application.
string 模块包括灵活多变的模版类(Template), 使最终用户具有适合编辑的简化语法. 这允许用户定制它们的应用而不用改变应用.
The format uses placeholder names formed by $
with valid Python identifiers (alphanumeric characters and underscores). Surrounding the placeholder with braces allows it to be followed by more alphanumeric letters with no intervening spaces. Writing $$
creates a single escaped $
:
>>> from string import Template
>>> t = Template('${village}folk send $$10 to $cause.')
>>> t.substitute(village='Nottingham', cause='the ditch fund')
'Nottinghamfolk send $10 to the ditch fund.'
格式用以 $
和有效的 Python 标识符(字符字符和下划线)占位符命名形式. 使用大括号围绕占位符允许其后跟更多的字母数字字母, 中间可以没有空格. 编写$$
创建一个单独的转义$
:
>>> from string import Template
>>> t = Template('${village}folk send $$10 to $cause.') # 大括号可以把替换字符嵌入字符串里
>>> t.substitute(village='Nottingham', cause='the ditch fund')
'Nottinghamfolk send $10 to the ditch fund.'
The substitute() method raises a KeyError when a placeholder is not supplied in a dictionary or a keyword argument. For mail-merge style applications, user supplied data may be incomplete and the safe_substitute() method may be more appropriate — it will leave placeholders unchanged if data is missing:
>>> t = Template('Return the $item to $owner.')
>>> d = dict(item='unladen swallow')
>>> t.substitute(d)
Traceback (most recent call last):
...
KeyError: 'owner'
>>> t.safe_substitute(d)
'Return the unladen swallow to $owner.'
当一个占位符提供的不是字典和关键字参数时, substitute() 模块抛出 KeyError 异常. 对于邮件合并格式应用, 用户提供的数据可能是不完整, 而 safe_substitute() 模块可能是更适当的 —— 如果数据遗失了, 它将使占位符保持不变:
>>> t = Template('Return the $item to $owner.')
>>> d = dict(item='unladen swallow')
>>> t.substitute(d)
Traceback (most recent call last): # 少了就报错
...
KeyError: 'owner'
>>> t.safe_substitute(d)
'Return the unladen swallow to $owner.' # 有多少就替换多少
Template subclasses can specify a custom delimiter. For example, a batch renaming utility for a photo browser may elect to use percent signs for placeholders such as the current date, image sequence number, or file format:
>>> import time, os.path
>>> photofiles = ['img_1074.jpg', 'img_1076.jpg', 'img_1077.jpg']
>>> class BatchRename(Template):
... delimiter = '%'
>>> fmt = input('Enter rename style (%d-date %n-seqnum %f-format): ')
Enter rename style (%d-date %n-seqnum %f-format): Ashley_%n%f
>>> t = BatchRename(fmt)
>>> date = time.strftime('%d%b%y')
>>> for i, filename in enumerate(photofiles):
... base, ext = os.path.splitext(filename)
... newname = t.substitute(d=date, n=i, f=ext)
... print('{0} --> {1}'.format(filename, newname))
img_1074.jpg --> Ashley_0.jpg
img_1076.jpg --> Ashley_1.jpg
img_1077.jpg --> Ashley_2.jpg
模板子类可以指定自定义分隔符. 例如, 照片浏览器的批量重命名实用程序可以选择使用百分号作为占位符, 比如当前日期, 图像序列号, 或文件格式:
>>> import time, os.path
>>> photofiles = ['img_1074.jpg', 'img_1076.jpg', 'img_1077.jpg']
>>> class BatchRename(Template):
... delimiter = '%'
...
>>> fmt = input('Enter rename style (%d-date %n-seqnum %f-format): ')
Enter rename style (%d-date %n-seqnum %f-format): Ashley_%n%f
>>> t = BatchRename(fmt)
>>> date = time.strftime('%d%b%y')
>>> for i, filename in enumerate(photofiles):
... base, ext = os.path.splitext(filename)
... newname = t.substitute(d=date, n=i, f=ext)
... print('{0} --> {1}'.format(filename, newname))
img_1074.jpg --> Ashley_0.jpg
img_1076.jpg --> Ashley_1.jpg
img_1077.jpg --> Ashley_2.jpg
Another application for templating is separating program logic from the details of multiple output formats. This makes it possible to substitute custom templates for XML files, plain text reports, and HTML web reports.
模板的另一个应用是将程序逻辑与多种输出格式的细节分开. 这使得替换 XML 文件, 纯文本报表, 和 HTML WEB 报表来定制模板成为可能.
The struct module provides pack() and unpack() functions for working with variable length binary record formats. The following example shows how to loop through header information in a ZIP file without using the zipfile module. Pack codes “H” and “I” represent two and four byte unsigned numbers respectively. The “<” indicates that they are standard size and in little-endian byte order:
import struct
with open('myfile.zip', 'rb') as f:
data = f.read()
start = 0
for i in range(3): # show the first 3 file headers
start += 14
fields = struct.unpack(', data[start:start+16])
crc32, comp_size, uncomp_size, filenamesize, extra_size = fields
start += 16
filename = data[start:start+filenamesize]
start += filenamesize
extra = data[start:start+extra_size]
print(filename, hex(crc32), comp_size, uncomp_size)
start += extra_size + comp_size # skip to the next header
struct 模块提供了 pack() 和 unpack() 函数用于处理可变长度二进制记录格式. 接下来的例子展示了在不使用 zipfile 模块的情况下如何迭代一个 ZIP 文件的头信息. 下面的示例演示了压缩码 “H” 和 “I” 分别表示2和4字节无符号数字, “<” 表明它们是标准大小和little-endian字节顺序:
import struct
with open('myfile.zip', 'rb') as f:
data = f.read()
start = 0
for i in range(3): # show the first 3 file headers
start += 14
fields = struct.unpack(', data[start:start+16])
crc32, comp_size, uncomp_size, filenamesize, extra_size = fields
start += 16
filename = data[start:start+filenamesize]
start += filenamesize
extra = data[start:start+extra_size]
print(filename, hex(crc32), comp_size, uncomp_size)
start += extra_size + comp_size # skip to the next header
Threading is a technique for decoupling tasks which are not sequentially dependent. Threads can be used to improve the responsiveness of applications that accept user input while other tasks run in the background. A related use case is running I/O in parallel with computations in another thread.
线程是一个分离无顺序依赖关系任务的技术. 线程可用于提高接受用户输入的应用程序的响应能力, 而其他任务在后台运行. 一个相关的用例是在另一个线程计算中平行运行 I/O.
The following code shows how the high level threading module can run tasks in background while the main program continues to run:
import threading, zipfile
class AsyncZip(threading.Thread):
def __init__(self, infile, outfile):
threading.Thread.__init__(self)
self.infile = infile
self.outfile = outfile
def run(self):
f = zipfile.ZipFile(self.outfile, 'w', zipfile.ZIP_DEFLATED)
f.write(self.infile)
f.close()
print('Finished background zip of:', self.infile)
background = AsyncZip('mydata.txt', 'myarchive.zip')
background.start()
print('The main program continues to run in foreground.')
background.join() # Wait for the background task to finish
print('Main program waited until background was done.')
下面的代码展示高级模块 threading可以运行任务在背景而主程序继续运行:
import threading, zipfile
class AsyncZip(threading.Thread):
def __init__(self, infile, outfile):
threading.Thread.__init__(self)
self.infile = infile
self.outfile = outfile
def run(self):
f = zipfile.ZipFile(self.outfile, 'w', zipfile.ZIP_DEFLATED)
f.write(self.infile)
f.close()
print('Finished background zip of:', self.infile)
background = AsyncZip('mydata.txt', 'myarchive.zip')
background.start()
print('The main program continues to run in foreground.')
background.join() # Wait for the background task to finish
print('Main program waited until background was done.')
The principal challenge of multi-threaded applications is coordinating threads that share data or other resources. To that end, the threading module provides a number of synchronization primitives including locks, events, condition variables, and semaphores.
多线程应用的主要挑战是协调线程, 也就是共享数据或其他资源. 为此目的, threading 模块提供了一些同步的原生函数, 包括: locks(锁), events(事件), condition variables(条件变量) 和 semaphores(信号灯).
While those tools are powerful, minor design errors can result in problems that are difficult to reproduce. So, the preferred approach to task coordination is to concentrate all access to a resource in a single thread and then use the queue module to feed that thread with requests from other threads. Applications using Queue objects for inter-thread communication and coordination are easier to design, more readable, and more reliable.
虽然这些工具很强大, 微小的的设计错误可能导致难以复制的问题. 所以, 任务协调的首选方法是集中所有的资源访问在一个单线程, 然后用 queue 模块为来自其他线程的请求提供该线程. 应用使用 Queue(队列) 对象来为 inter-thread(内部线程) 通信和协调是很容易设计, 更易读, 且更可靠的.
The logging module offers a full featured and flexible logging system. At its simplest, log messages are sent to a file or to sys.stderr:
import logging
logging.debug('Debugging information')
logging.info('Informational message')
logging.warning('Warning:config file %s not found', 'server.conf')
logging.error('Error occurred')
logging.critical('Critical error -- shutting down')
This produces the following output:
WARNING:root:Warning:config file server.conf not found
ERROR:root:Error occurred
CRITICAL:root:Critical error -- shutting down
logging 模块提供功能完整, 灵活多变的日志系统. 最简单的是, 日志信息推送到文件或sys.stderr:
import logging
logging.debug('Debugging information')
logging.info('Informational message')
logging.warning('Warning:config file %s not found', 'server.conf')
logging.error('Error occurred')
logging.critical('Critical error -- shutting down')
这产生如下的输出:
WARNING:root:Warning:config file server.conf not found
ERROR:root:Error occurred
CRITICAL:root:Critical error -- shutting down
By default, informational and debugging messages are suppressed and the output is sent to standard error. Other output options include routing messages through email, datagrams, sockets, or to an HTTP Server. New filters can select different routing based on message priority: DEBUG, INFO, WARNING, ERROR, and CRITICAL.
默认情况下, 信息和调试信息是被支持的, 输出被发送给标准错误. 其他输出选项包括通过 email, datagrams(数据报文), sockets, 或 HTTP 服务器的路由信息. 新过滤器可以基于信息优先权选择不同路由: DEBUG, INFO, WARNING, ERROR, and CRITICAL.
The logging system can be configured directly from Python or can be loaded from a user editable configuration file for customized logging without altering the application.
日志记录系统可以直接从Python配置, 也可以从用户可编辑的配置文件加载, 以便自定义日志记录而无需更改应用程序.
Python does automatic memory management (reference counting for most objects and garbage collection to eliminate cycles). The memory is freed shortly after the last reference to it has been eliminated.
Python 自动进行内存管理(大多数对象的引用计数和垃圾收集以消除周期). 在消除了对它的最后一次引用后不久释放内存.
This approach works fine for most applications but occasionally there is a need to track objects only as long as they are being used by something else. Unfortunately, just tracking them creates a reference that makes them permanent. The weakref module provides tools for tracking objects without creating a reference. When the object is no longer needed, it is automatically removed from a weakref table and a callback is triggered for weakref objects. Typical applications include caching objects that are expensive to create:
>>> import weakref, gc
>>> class A:
... def __init__(self, value):
... self.value = value
... def __repr__(self):
... return str(self.value)
...
>>> a = A(10) # create a reference
>>> d = weakref.WeakValueDictionary()
>>> d['primary'] = a # does not create a reference
>>> d['primary'] # fetch the object if it is still alive
10
>>> del a # remove the one reference
>>> gc.collect() # run garbage collection right away
0
>>> d['primary'] # entry was automatically removed
Traceback (most recent call last):
File "" , line 1, in <module>
d['primary'] # entry was automatically removed
File "C:/python36/lib/weakref.py", line 46, in __getitem__
o = self.data[key]()
KeyError: 'primary'
这种工作方式对大多数应用很友好, 但偶尔需要跟踪对象, 只要他们正在被其他东西使用. 不幸的是, 只是跟踪它们会创建一个使它们永久化的引用. weakref 模块提供了跟踪对象不用创建引用的工具. 当对象不是长久需要的, 它自动从弱引用表删除, 然后触发一个弱引用对象回调函数. 典型应用包含捕获难以构造的对象:
>>> import weakref, gc
>>> class A:
... def __init__(self, value):
... self.value = value
... def __repr__(self):
... return str(self.value)
...
>>> a = A(10) # create a reference
>>> d = weakref.WeakValueDictionary()
>>> d['primary'] = a # does not create a reference
>>> d['primary'] # fetch the object if it is still alive
10
>>> del a # remove the one reference
>>> gc.collect() # run garbage collection right away
0
>>> d['primary'] # entry was automatically removed
Traceback (most recent call last):
File "" , line 1, in <module>
d['primary'] # entry was automatically removed
File "C:/python36/lib/weakref.py", line 46, in __getitem__
o = self.data[key]()
KeyError: 'primary'
Many data structure needs can be met with the built-in list type. However, sometimes there is a need for alternative implementations with different performance trade-offs.
内置列表类型可以满足许多数据结构需求. 然而, 有时候需要替代实现针对不同的性能权衡.
The array module provides an array() object that is like a list that stores only homogeneous data and stores it more compactly. The following example shows an array of numbers stored as two byte unsigned binary numbers (typecode “H”) rather than the usual 16 bytes per entry for regular lists of Python int objects:
>>> from array import array
>>> a = array('H', [4000, 10, 700, 22222])
>>> sum(a)
26932
>>> a[1:3]
array('H', [10, 700])
array 模块提供一个类似列表的对象, 它只存储同质数据, 且更加简洁.下面的示例演示了一个存储双字节无符号整数的数组(类型编码 “H”)而非存储 16 字节 Python 整数对象的普通正规列表:
>>> from array import array
>>> a = array('H', [4000, 10, 700, 22222])
>>> sum(a)
26932
>>> a[1:3]
array('H', [10, 700])
The collections module provides a deque() object that is like a list with faster appends and pops from the left side but slower lookups in the middle. These objects are well suited for implementing queues and breadth first tree searches:
>>> from collections import deque
>>> d = deque(["task1", "task2", "task3"])
>>> d.append("task4")
>>> print("Handling", d.popleft())
Handling task1
unsearched = deque([starting_node])
def breadth_first_search(unsearched):
node = unsearched.popleft()
for m in gen_moves(node):
if is_goal(m):
return m
unsearched.append(m)
collections(集合) 模块提供了一个 deque() 对象, 它类似列表, 能更快地从左侧添加和抛出, 但在中间查找更慢. 这些对象很适合实现队列和广度优先的树搜索:
>>> from collections import deque
>>> d = deque(["task1", "task2", "task3"])
>>> d.append("task4")
>>> print("Handling", d.popleft())
Handling task1
unsearched = deque([starting_node])
def breadth_first_search(unsearched):
node = unsearched.popleft()
for m in gen_moves(node):
if is_goal(m):
return m
unsearched.append(m)
In addition to alternative list implementations, the library also offers other tools such as the bisect module with functions for manipulating sorted lists:
>>> import bisect
>>> scores = [(100, 'perl'), (200, 'tcl'), (400, 'lua'), (500, 'python')]
>>> bisect.insort(scores, (300, 'ruby'))
>>> scores
[(100, 'perl'), (200, 'tcl'), (300, 'ruby'), (400, 'lua'), (500, 'python')]
除了替代列表实现, 这个库还提供了其他工具, 如 bisect 模块具有操作排序列表的功能:
>>> import bisect
>>> scores = [(100, 'perl'), (200, 'tcl'), (400, 'lua'), (500, 'python')]
>>> bisect.insort(scores, (300, 'ruby'))
>>> scores
[(100, 'perl'), (200, 'tcl'), (300, 'ruby'), (400, 'lua'), (500, 'python')]
The heapq module provides functions for implementing heaps based on regular lists. The lowest valued entry is always kept at position zero. This is useful for applications which repeatedly access the smallest element but do not want to run a full list sort:
>>> from heapq import heapify, heappop, heappush
>>> data = [1, 3, 5, 7, 9, 2, 4, 6, 8, 0]
>>> heapify(data) # rearrange the list into heap order
>>> heappush(data, -5) # add a new entry
>>> [heappop(data) for i in range(3)] # fetch the three smallest entries
[-5, 0, 1]
heapq 模块为基于列表规则实现堆提供函数. 最小值的条目总是保持在位置零. 这对应用反复访问最小元素但不想去运行整个列表排序很有用:
>>> from heapq import heapify, heappop, heappush
>>> data = [1, 3, 5, 7, 9, 2, 4, 6, 8, 0]
>>> heapify(data) # rearrange the list into heap order
>>> heappush(data, -5) # add a new entry
>>> [heappop(data) for i in range(3)] # fetch the three smallest entries
[-5, 0, 1]
The decimal module offers a Decimal datatype for decimal floating point arithmetic. Compared to the built-in float implementation of binary floating point, the class is especially helpful for
decimal 模块提供一个十进制数据类型, 为了十进制浮点数算法. 相比于内置的 float 二进制浮点数实现, 这个类尤其有助于:
For example, calculating a 5% tax on a 70 cent phone charge gives different results in decimal floating point and binary floating point. The difference becomes significant if the results are rounded to the nearest cent:
>>> from decimal import *
>>> round(Decimal('0.70') * Decimal('1.05'), 2)
Decimal('0.74')
>>> round(.70 * 1.05, 2)
0.73
例如, 计算 70 分电话费的 5% 税, 十进制浮点数和二进制浮点数给出了不同的结果. 如果结果四舍五入到附件的值, 这个差异会变得更大:
>>> from decimal import *
>>> round(Decimal('0.70') * Decimal('1.05'), 2)
Decimal('0.74')
>>> round(.70 * 1.05, 2)
0.73
The Decimal result keeps a trailing zero, automatically inferring four place significance from multiplicands with two place significance. Decimal reproduces mathematics as done by hand and avoids issues that can arise when binary floating point cannot exactly represent decimal quantities.
十进制结果保持尾随零, 自动从两位精度延伸到4位. 十进制再现了手动数学运算, 避免了当二进制浮点数不能精确表示十进制数量时问题抛出(确保了二进制浮点数无法精确保有的数据精度, 译注).
Exact representation enables the Decimal class to perform modulo calculations and equality tests that are unsuitable for binary floating point:
>>> Decimal('1.00') % Decimal('.10')
Decimal('0.00')
>>> 1.00 % 0.10
0.09999999999999995
>>> sum([Decimal('0.1')]*10) == Decimal('1.0')
True
>>> sum([0.1]*10) == 1.0
False
精确的表示使 Decimal 类可以执行二进制浮点数无法进行的模运算和等值测试:
>>> Decimal('1.00') % Decimal('.10')
Decimal('0.00')
>>> 1.00 % 0.10
0.09999999999999995
>>> sum([Decimal('0.1')]*10) == Decimal('1.0')
True
>>> Decimal('0.1') * 10 == Decimal('1.0')
True
>>> sum([0.1]*10) == 1.0
False
The decimal module provides arithmetic with as much precision as needed:
>>> getcontext().prec = 36
>>> Decimal(1) / Decimal(7)
Decimal('0.142857142857142857142857142857142857')
十进制模块根据需要提供尽可能高的算术运算:
>>> getcontext().prec = 36
>>> Decimal(1) / Decimal(7)
Decimal('0.142857142857142857142857142857142857')
CHAPTER
TWELVE
Python applications will often use packages and modules that don’t come as part of the standard library. Applications will sometimes need a specific version of a library, because the application may require that a particular bug has been fixed or the application may be written using an obsolete version of the library’s interface.
Python 应用经常会使用那些不是标准库一部分的包和模块. 有时应用会需要一个特定的库版本, 因为这个应用可能需要特定 bug 已经被修复, 或这个应用可能写作于一个过时的库接口的版本.
This means it may not be possible for one Python installation to meet the requirements of every application. If application A needs version 1.0 of a particular module but application B needs version 2.0, then the requirements are in conflict and installing either version 1.0 or 2.0 will leave one application unable to run.
这意味着一个 Python 解释器去满足每个应用的需求是不可能的. 如果应用 A 需要特定模块的版本 1.0, 但应用 B 需要版本 2.0, 这样需求就冲突了, 而无论安装版本 1.0 还是 2.0 都讲使一个应用不能运行.
The solution for this problem is to create a virtual environment, a self-contained directory tree that contains
a Python installation for a particular version of Python, plus a number of additional packages.
这个问题的解决方案是创建一个虚拟环境, 是一个独享的目录树, 它包含一个特定 Python 版本的 Python解释器, 加上一些额外的包.
Different applications can then use different virtual environments. To resolve the earlier example of conflicting requirements, application A can have its own virtual environment with version 1.0 installed while application B has another virtual environment with version 2.0. If application B requires a library be upgraded to version 3.0, this will not affect application A’s environment.
不同的应用可以使用不同的虚拟环境. 要解决前面冲突案例的需求, 应用 A 可以有它自己的安装有版本 1.0 的虚拟环境, 而应用 B 有另一个装有版本 2.0 的虚拟环境. 这样, 如果应用 B 需要库升级到版本 3.0, 也不会影响到应用 A 的环境.
The module used to create and manage virtual environments is called venv. venv will usually install the most recent version of Python that you have available. If you have multiple versions of Python on your system, you can select a specific Python version by running python3 or whichever version you want.
用于创建和管理虚拟环境的模块称为 venv. venv 通常可安装可用的 Python 的大多数最近版本. 如果在你的系统中有多个Python版本, 你可以选择指定的 Python 版本来运行 python3 或其他你想要的版本.
To create a virtual environment, decide upon a directory where you want to place it, and run the venv module as a script with the directory path:
python3 -m venv tutorial-env
要创建一个虚拟环境, 决定一个你想存放它的目录, 然后在这个目录下将 venv 模块当做脚本来运行:
python3 -m venv tutorial-env
This will create the tutorial-env directory if it doesn’t exist, and also create directories inside it containing a copy of the Python interpreter, the standard library, and various supporting files.
这将创建一个 tutorial-env 目录, 如果它不存在的话, 然后在里面创建目录, 这些目录包含 Python 解释器, 标准库, 和版本支持文件.
Once you’ve created a virtual environment, you may activate it.
On Windows, run:
tutorial-env\Scripts\activate.bat
On Unix or MacOS, run:
source tutorial-env/bin/activate
(This script is written for the bash shell. If you use the csh or fish shells, there are alternate activate.csh and activate.fish scripts you should use instead.)
一旦你创建了虚拟环境后, 你就可以激活它.
在 Windows, 运行:
.\tutorial-env\Scripts\activate.bat
在 Unix 或 MacOS, 运行:
source tutorial-env/bin/activate
Activating the virtual environment will change your shell’s prompt to show what virtual environment you’re using, and modify the environment so that running python will get you that particular version and installation of Python. For example:
$ source ~/envs/tutorial-env/bin/activate
(tutorial-env) $ python
Python 3.5.1 (default, May 6 2016, 10:59:36)
...
>>> import sys
>>> sys.path
['', '/usr/local/lib/python35.zip', ...,
'~/envs/tutorial-env/lib/python3.5/site-packages']
>>>
激活虚拟环境将更改shell的提示, 以显示您正在使用的虚拟环境, 然后修改环境, 这样运行 python 将给你 Python 的特定版本和解释器. 例如:
$ source ~/envs/tutorial-env/bin/activate
(tutorial-env) $ python
Python 3.5.1 (default, May 6 2016, 10:59:36)
...
>>> import sys
>>> sys.path
['', '/usr/local/lib/python35.zip', ...,
'~/envs/tutorial-env/lib/python3.5/site-packages']
>>>
You can install, upgrade, and remove packages using a program called pip. By default pip will install packages from the Python Package Index, https://pypi.org. You can browse the Python Package Index by going to it in your web browser, or you can use pip’s limited search feature:
(tutorial-env) $ pip search astronomy
skyfield - Elegant astronomy for Python
gary - Galactic astronomy and gravitational dynamics.
novas - The United States Naval Observatory NOVAS astronomy library
astroobs - Provides astronomy ephemeris to plan telescope observations
PyAstronomy - A collection of astronomy related tools for Python
...
pip has a number of subcommands: “search”, “install”, “uninstall”, “freeze”, etc. (Consult the installingi-ndex guide for complete documentation for pip.)
您可以使用名为pip的程序安装, 升级和删除软件包. 默认情况下, pip将从Python Package Index https://pypi.org安装软件包. 您可以在Web浏览器中浏览Python Package Index, 也可以使用pip的有限搜索功能:
(tutorial-env) $ pip search astronomy
skyfield - Elegant astronomy for Python
gary - Galactic astronomy and gravitational dynamics.
novas - The United States Naval Observatory NOVAS astronomy library
astroobs - Provides astronomy ephemeris to plan telescope observations
PyAstronomy - A collection of astronomy related tools for Python
...
pip有许多子命令: “search”, “install”, “uninstall”, “freeze”, 等等. (有关pip的完整文档, 请参阅安装指南.)
You can install the latest version of a package by specifying a package’s name:
(tutorial-env) $ pip install novas
Collecting novas
Downloading novas-3.1.1.3.tar.gz (136kB)
Installing collected packages: novas
Running setup.py install for novas
Successfully installed novas-3.1.1.3
你可以通过指定包名安装最新版本的包:
(tutorial-env) $ pip install novas
Collecting novas
Downloading novas-3.1.1.3.tar.gz (136kB)
Installing collected packages: novas
Running setup.py install for novas
Successfully installed novas-3.1.1.3
You can also install a specific version of a package by giving the package name followed by == and the version number:
(tutorial-env) $ pip install requests==2.6.0
Collecting requests==2.6.0
Using cached requests-2.6.0-py2.py3-none-any.whl
Installing collected packages: requests
Successfully installed requests-2.6.0
你也可以通过在包名后面跟 == 和版本号来安装指定的包版本:
(tutorial-env) $ pip install requests==2.6.0
Collecting requests==2.6.0
Using cached requests-2.6.0-py2.py3-none-any.whl
Installing collected packages: requests
Successfully installed requests-2.6.0
If you re-run this command, pip will notice that the requested version is already installed and do nothing. You can supply a different version number to get that version, or you can run pip install --upgrade to upgrade the package to the latest version:
(tutorial-env) $ pip install --upgrade requests
Collecting requests
Installing collected packages: requests
Found existing installation: requests 2.6.0
Uninstalling requests-2.6.0:
Successfully uninstalled requests-2.6.0
Successfully installed requests-2.7.0
如果你重新运行这个命名, pip 将注意这个请求版本是已经安装的然后什么都不做. 你可以提供一个不同的版本号去获取这个版本, 或你可以运行 pip install --upgrade 去更新包到最新版本:
(tutorial-env) $ pip install --upgrade requests
Collecting requests
Installing collected packages: requests
Found existing installation: requests 2.6.0
Uninstalling requests-2.6.0:
Successfully uninstalled requests-2.6.0
Successfully installed requests-2.7.0
pip uninstall followed by one or more package names will remove the packages from the virtual environment.
pip uninstall 后跟一个或多个报名, 将从虚拟环境中移除包.
pip show will display information about a particular package:
(tutorial-env) $ pip show requests
---
Metadata-Version: 2.0
Name: requests
Version: 2.7.0
Summary: Python HTTP for Humans.
Home-page: http://python-requests.org
Author: Kenneth Reitz
Author-email: [email protected]
License: Apache 2.0
Location: /Users/akuchling/envs/tutorial-env/lib/python3.4/site-packages
Requires:
pip show 将显示关于特定包的信息:
(tutorial-env) $ pip show requests
---
Metadata-Version: 2.0
Name: requests
Version: 2.7.0
Summary: Python HTTP for Humans.
Home-page: http://python-requests.org
Author: Kenneth Reitz
Author-email: [email protected]
License: Apache 2.0
Location: /Users/akuchling/envs/tutorial-env/lib/python3.4/site-packages
Requires:
pip list will display all of the packages installed in the virtual environment:
(tutorial-env) $ pip list
novas (3.1.1.3)
numpy (1.9.2)
pip (7.0.3)
requests (2.7.0)
setuptools (16.0)
pip list 将显示虚拟环境中所有已安装的包:
(tutorial-env) $ pip list
novas (3.1.1.3)
numpy (1.9.2)
pip (7.0.3)
requests (2.7.0)
setuptools (16.0)
pip freeze will produce a similar list of the installed packages, but the output uses the format that pip install expects. A common convention is to put this list in a requirements.txt file:
(tutorial-env) $ pip freeze > requirements.txt
(tutorial-env) $ cat requirements.txt
novas==3.1.1.3
numpy==1.9.2
requests==2.7.0
pip freeze 将产生一个安装包的类似列表, 但输出使用 pip install 期望的格式. 一个常见的惯例是将此列表放在 requirements.txt 文件中
(tutorial-env) $ pip freeze > requirements.txt
(tutorial-env) $ cat requirements.txt
novas==3.1.1.3
numpy==1.9.2
requests==2.7.0
The requirements.txt can then be committed to version control and shipped as part of an application. Users can then install all the necessary packages with install -r:
(tutorial-env) $ pip install -r requirements.txt
Collecting novas==3.1.1.3 (from -r requirements.txt (line 1))
...
Collecting numpy==1.9.2 (from -r requirements.txt (line 2))
...
Collecting requests==2.7.0 (from -r requirements.txt (line 3))
...
Installing collected packages: novas, numpy, requests
Running setup.py install for novas
Successfully installed novas-3.1.1.3 numpy-1.9.2 requests-2.7.0
requirements.txt 可以提交版本控制并作为应用程序的一部分提供. 用户稍后可以用 install -r 安装所有的需求包:
(tutorial-env) $ pip install -r requirements.txt
Collecting novas==3.1.1.3 (from -r requirements.txt (line 1))
...
Collecting numpy==1.9.2 (from -r requirements.txt (line 2))
...
Collecting requests==2.7.0 (from -r requirements.txt (line 3))
...
Installing collected packages: novas, numpy, requests
Running setup.py install for novas
Successfully installed novas-3.1.1.3 numpy-1.9.2 requests-2.7.0
pip has many more options. Consult the installing-index guide for complete documentation for pip. When you’ve written a package and want to make it available on the Python Package Index, consult the distributing-index guide.
pip 有更多的可选项. 参考安装指南查看完整的 pip 文档. 当你已经写了一个包且想使它可以在 Python Package Index 可获取, 参考 文档字符串指南.