10. Python æ ‡å‡†åº“æ¦‚è§ˆÂ¶
10.1. �作系统接�¶
os 模��供了很多与�作系统交互的函数:
>>> import os
>>> os.getcwd() # Return the current working directory
'C:\\Python35'
>>> os.chdir('/server/accesslogs') # Change current working directory
>>> os.system('mkdir today') # Run the command mkdir in the system shell
0
应该用 import os é£Žæ ¼è€Œé�ž from os import *ã€‚è¿™æ ·å�¯ä»¥ä¿�è¯�éš�æ“�作系统ä¸�å�Œè€Œæœ‰æ‰€å�˜åŒ–çš„ os.open() ä¸�会覆盖内置函数 open()。
在使用一些åƒ� os è¿™æ ·çš„å¤§åž‹æ¨¡å�—时内置的 dir() å’Œ help() 函数é�žå¸¸æœ‰ç”¨:
>>> import os
>>> dir(os)
<returns a list of all module functions>
>>> help(os)
<returns an extensive manual page created from the module's docstrings>
针对日常的文件和目录管�任务,shutil 模��供了一个易于使用的高级接�:
>>> import shutil
>>> shutil.copyfile('data.db', 'archive.db')
'archive.db'
>>> shutil.move('/build/executables', 'installdir')
'installdir'
10.2. 文件通�符¶
glob 模å�—æ��供了一个函数用于从目录通é…�符æ�œç´¢ä¸ç”Ÿæˆ�文件列表:
>>> import glob
>>> glob.glob('*.py')
['primes.py', 'random.py', 'quote.py']
10.3. 命令行�数¶
通用工具脚本ç»�常调用命令行å�‚数。这些命令行å�‚数以链表形å¼�å˜å‚¨äºŽ sys 模å�—çš„ argv å�˜é‡�ã€‚ä¾‹å¦‚åœ¨å‘½ä»¤è¡Œä¸æ‰§è¡Œ python demo.py one two three å�Žå�¯ä»¥å¾—到以下输出结果:
>>> import sys
>>> print(sys.argv)
['demo.py', 'one', 'two', 'three']
getopt 模�使用 Unix getopt() 函数处� sys.argv。更多的��命令行处�由 argparse 模��供。
10.4. 错误输出é‡�定å�‘和程åº�终æ¢Â¶
sys 还有 stdin, stdout å’Œ stderr 属性,å�³ä½¿åœ¨ stdout 被é‡�定å�‘时,å�Žè€…也å�¯ä»¥ç”¨äºŽæ˜¾ç¤ºè¦å‘Šå’Œé”™è¯¯ä¿¡æ�¯:
>>> sys.stderr.write('Warning, log file not found starting a new one\n')
Warning, log file not found starting a new one
大多脚本的直接终æ¢éƒ½ä½¿ç”¨ sys.exit()。
10.5. å—符串æ£åˆ™åŒ¹é…�¶
re 模å�—为高级å—符串处ç�†æ��供了æ£åˆ™è¡¨è¾¾å¼�工具。对于å¤�æ�‚的匹é…�和处ç�†ï¼Œæ£åˆ™è¡¨è¾¾å¼�æ��供了简æ´�ã€�优化的解决方案:
>>> import re
>>> re.findall(r'\bf[a-z]*', 'which foot or hand fell fastest')
['foot', 'fell', 'fastest']
>>> re.sub(r'(\b[a-z]+) \1', r'\1', 'cat in the the hat')
'cat in the hat'
å�ªéœ€ç®€å�•çš„æ“�作时,å—ç¬¦ä¸²æ–¹æ³•æœ€å¥½ç”¨ï¼Œå› ä¸ºå®ƒä»¬æ˜“è¯»ï¼Œå�ˆå®¹æ˜“调试:
>>> 'tea for too'.replace('too', 'two')
'tea for two'
10.6. æ•°å¦Â¶
math 模�为浮点�算�供了对底层C函数库的访问:
>>> import math
>>> math.cos(math.pi / 4.0)
0.70710678118654757
>>> math.log(1024, 2)
10.0
random �供了生��机数的工具:
>>> import random
>>> random.choice(['apple', 'pear', 'banana'])
'apple'
>>> random.sample(range(100), 10) # sampling without replacement
[30, 83, 16, 4, 8, 81, 41, 50, 18, 33]
>>> random.random() # random float
0.17970987693706186
>>> random.randrange(6) # random integer chosen from range(6)
4
SciPy <http://scipy.org> 项目�供了许多数值计算的模�。
10.7. 互�网访问¶
æœ‰å‡ ä¸ªæ¨¡å�—用于访问互è�”网以å�Šå¤„ç�†ç½‘络通信å��è®®ã€‚å…¶ä¸æœ€ç®€å�•的两个是用于处ç�†ä»Ž urls 接收的数æ�®çš„ urllib.request 以å�Šç”¨äºŽå�‘é€�电å�邮件的 smtplib:
>>> from urllib.request import urlopen
>>> for line in urlopen('http://tycho.usno.navy.mil/cgi-bin/timer.pl'):
... line = line.decode('utf-8') # Decoding the binary data to text.
... if 'EST' in line or 'EDT' in line: # look for Eastern Time
... print(line)
<BR>Nov. 25, 09:43:32 PM EST
>>> import smtplib
>>> server = smtplib.SMTP('localhost')
>>> server.sendmail('soothsayer@example.org', 'jcaesar@example.org',
... """To: jcaesar@example.org
... From: soothsayer@example.org
...
... Beware the Ides of March.
... """)
>>> server.quit()
(注æ„�第二个例å�需è¦�在 localhost è¿�行一个邮件æœ�务器。)
10.8. 日期和时间¶
datetime 模å�—为日期和时间处ç�†å�Œæ—¶æ��供了简å�•å’Œå¤�æ�‚的方法。支æŒ�日期和时间算法的å�Œæ—¶ï¼Œå®žçŽ°çš„é‡�点放在更有效的处ç�†å’Œæ ¼å¼�化输出。该模å�—还支æŒ�时区处ç�†ã€‚
>>> # dates are easily constructed and formatted
>>> from datetime import date
>>> now = date.today()
>>> now
datetime.date(2003, 12, 2)
>>> now.strftime("%m-%d-%y. %d %b %Y is a %A on the %d day of %B.")
'12-02-03. 02 Dec 2003 is a Tuesday on the 02 day of December.'
>>> # dates support calendar arithmetic
>>> birthday = date(1964, 7, 31)
>>> age = now - birthday
>>> age.days
14368
10.9. 数�压缩¶
以下模å�—直接支æŒ�通用的数æ�®æ‰“åŒ…å’ŒåŽ‹ç¼©æ ¼å¼�:zlib, gzip, bz2, lzma, zipfile 以å�Š tarfile。
>>> import zlib
>>> s = b'witch which has which witches wrist watch'
>>> len(s)
41
>>> t = zlib.compress(s)
>>> len(t)
37
>>> zlib.decompress(t)
b'witch which has which witches wrist watch'
>>> zlib.crc32(s)
226805979
10.10. 性能度�¶
有些用户对了解解决å�Œä¸€é—®é¢˜çš„ä¸�å�Œæ–¹æ³•之间的性能差异很感兴趣。Python æ��供了一个度é‡�工具,为这些问题æ��ä¾›äº†ç›´æŽ¥ç”æ¡ˆã€‚
例如,使用元组å°�装和拆å°�æ�¥äº¤æ�¢å…ƒç´ 看起æ�¥è¦�æ¯”ä½¿ç”¨ä¼ ç»Ÿçš„æ–¹æ³•è¦�诱人的多。timeit è¯�明了å�Žè€…更快一些:
>>> from timeit import Timer
>>> Timer('t=a; a=b; b=t', 'a=1; b=2').timeit()
0.57535828626024577
>>> Timer('a,b = b,a', 'a=1; b=2').timeit()
0.54962537085770791
相对于 timeit 的细粒度,profile å’Œ pstats 模å�—æ��供了针对更大代ç �å�—的时间度é‡�工具。
10.11. 质�控制¶
å¼€å�‘高质é‡�软件的方法之一是为æ¯�一个函数开å�‘测试代ç �,并且在开å�‘过程ä¸ç»�常进行测试。
doctest 模å�—æ��供了一个工具,扫æ��模å�—å¹¶æ ¹æ�®ç¨‹åº�ä¸å†…嵌的文档å—ç¬¦ä¸²æ‰§è¡Œæµ‹è¯•ã€‚æµ‹è¯•æž„é€ å¦‚å�Œç®€å�•的将它的输出结果剪切并粘贴到文档å—符串ä¸ã€‚通过用户æ��供的例å�,它å�‘展了文档,å…�许 doctest 模å�—确认代ç �的结果是å�¦ä¸Žæ–‡æ¡£ä¸€è‡´:
def average(values):
"""Computes the arithmetic mean of a list of numbers.
>>> print(average([20, 30, 70]))
40.0
"""
return sum(values) / len(values)
import doctest
doctest.testmod() # automatically validate the embedded tests
unittest 模��� doctest 模�那么容易使用,�过它�以在一个独立的文件里�供一个更全�的测试集:
import unittest
class TestStatisticalFunctions(unittest.TestCase):
def test_average(self):
self.assertEqual(average([20, 30, 70]), 40.0)
self.assertEqual(round(average([1, 5, 7]), 1), 4.3)
with self.assertRaises(ZeroDivisionError):
average([])
with self.assertRaises(TypeError):
average(20, 30, 70)
unittest.main() # Calling from the command line invokes all tests
10.12. “瑞士军刀�¶
Python 展现了“瑞士军刀â€�的哲å¦ã€‚è¿™å�¯ä»¥é€šè¿‡å®ƒæ›´å¤§çš„包的高级和å�¥å£®çš„功能æ�¥å¾—到最好的展现。列如:
xmlrpc.client å’Œ xmlrpc.server 模å�—让远程过程调用å�˜å¾—轻而易举。尽管模å�—æœ‰è¿™æ ·çš„å��å—ï¼Œç”¨æˆ·æ— éœ€æ‹¥æœ‰ XML 的知识或处ç�† XML。
email 包是一个管�邮件信�的库,包括MIME和其它基于 RFC2822 的信�文档。
ä¸�å�ŒäºŽå®žé™…å�‘é€�和接收信æ�¯çš„ smtplib å’Œ poplib 模å�—,email 包包å�«ä¸€ä¸ªæž„é€ æˆ–è§£æž�å¤�æ�‚消æ�¯ç»“构(包括附件)å�Šå®žçŽ°äº’è�”网编ç �和头å��议的完整工具集。
xml.dom å’Œ xml.sax 包为æµ�行的信æ�¯äº¤æ�¢æ ¼å¼�æ��供了强大的支æŒ�。å�Œæ ·ï¼Œ csv 模å�—支æŒ�在通用数æ�®åº“æ ¼å¼�ä¸ç›´æŽ¥è¯»å†™ã€‚
综�起�,这些模�和包大大简化了 Python 应用程�和其它工具之间的数�交�。