Python标准库简介

1.操作系统接口

os模块提供了许多与操作系统交互的函数:

>>> import os
>>> os.getcwd() # Return the current working directory
'C:\\Users\\Windows10'
>>> os.chdir('./Desktop')  # Change current working directory
>>> os.getcwd()
'C:\\Users\\Windows10\\Desktop'
>>> os.system('mkdir test01')  # Run the command mkdir in the system shell
0
>>>

一定要是用import os而不是from os import *。这将避免内建open()函数被os.open()函数隐式替换,因为它们的使用方法大不形同。

内置的dir()和help()函数可用作交互式辅助工具,用于处理大型模块,如os:

>>> import os
>>> dir(os)
['DirEntry', 'F_OK', 'GenericAlias', 'Mapping', 'MutableMapping', 'O_APPEND', 'O_BINARY', 'O_CREAT', 'O_EXCL', 'O_NOINHERIT', 'O_RANDOM', 'O_RDONLY', 'O_RDWR', 'O_SEQUENTIAL', 'O_SHORT_LIVED', 'O_TEMPORARY', 'O_TEXT', 'O_TRUNC', 'O_WRONLY', 'P_DETACH', 'P_NOWAIT', 'P_NOWAITO', 'P_OVERLAY', 'P_WAIT', 'PathLike', 'R_OK', 'SEEK_CUR', 'SEEK_END', 'SEEK_SET', 'TMP_MAX', 'W_OK', 'X_OK', '_AddedDllDirectory', '_Environ', '__all__', '__builtins__', '__cached__', '__doc__', '__file__', '__loader__', '__name__', '__package__', '__spec__', '_check_methods', '_execvpe', '_exists', '_exit', '_fspath', '_get_exports_list', '_walk', '_wrap_close', 'abc', 'abort', 'access', 'add_dll_directory', 'altsep', 'chdir', 'chmod', 'close', 'closerange', 'cpu_count', 'curdir', 'defpath', 'device_encoding', 'devnull', 'dup', 'dup2', 'environ', 'error', 'execl', 'execle', 'execlp', 'execlpe', 'execv', 'execve', 'execvp', 'execvpe', 'extsep', 'fdopen', 'fsdecode', 'fsencode', 'fspath', 'fstat', 'fsync', 'ftruncate', 'get_exec_path', 'get_handle_inheritable', 'get_inheritable', 'get_terminal_size', 'getcwd', 'getcwdb', 'getenv', 'getlogin', 'getpid', 'getppid', 'isatty', 'kill', 'linesep', 'link', 'listdir', 'lseek', 'lstat', 'makedirs', 'mkdir', 'name', 'open', 'pardir', 'path', 'pathsep', 'pipe', 'popen', 'putenv', 'read', 'readlink', 'remove', 'removedirs', 'rename', 'renames', 'replace', 'rmdir', 'scandir', 'sep', 'set_handle_inheritable', 'set_inheritable', 'spawnl', 'spawnle', 'spawnv', 'spawnve', 'st', 'startfile', 'stat', 'stat_result', 'statvfs_result', 'strerror', 'supports_bytes_environ', 'supports_dir_fd', 'supports_effective_ids', 'supports_fd', 'supports_follow_symlinks', 'symlink', 'sys', 'system', 'terminal_size', 'times', 'times_result', 'truncate', 'umask', 'uname_result', 'unlink', 'unsetenv', 'urandom', 'utime', 'waitpid', 'waitstatus_to_exitcode', 'walk', 'write']
>>> help(os)
Help on module os:

NAME
    os - OS routines for NT or Posix depending on what system we're on.

MODULE REFERENCE
    https://docs.python.org/3.10/library/os.html

    The following documentation is automatically generated from the Python
    source files.  It may be incomplete, incorrect or include features that
    are considered implementation detail and may vary between Python
    implementations.  When in doubt, consult the module reference at the
    location listed above.

DESCRIPTION
    This exports:
      - all functions from posix or nt, e.g. unlink, stat, etc.
      - os.path is either posixpath or ntpath
      - os.name is either 'posix' or 'nt'
      - os.curdir is a string representing the current directory (always '.')
      - os.pardir is a string representing the parent directory (always '..')
      - os.sep is the (or a most common) pathname separator ('/' or '\\')
      - os.extsep is the extension separator (always '.')
      - os.altsep is the alternate pathname separator (None or '/')
      - os.pathsep is the component separator used in $PATH etc
      - os.linesep is the line separator in text files ('\r' or '\n' or '\r\n')
      - os.defpath is the default search path for executables
      - os.devnull is the file path of the null device ('/dev/null', etc.)

-- More  --

对于日常文件和目录管理任务,shutil模块提供了更易于使用的更高级别的接口:

>>> import shutil
>>> shutil.copyfile('RegexSample.java', 'RS.java')
'RS.java'
>>> shutil.move('RS.java', './test01')
'./test01\\RS.java'

2.文件通配符

glob模块提供了一个在目录中使用通配符搜索创建文件列表的函数:

>>> import glob
>>> glob.glob('*.java')
['RegexSample.java', 'RS.java']

3.命令行参数

通用实用程序脚本通常需要处理命令行参数。这些参数作为列表存储在sys模块的argv属性中。例如,以下输出来自在命令行运行python demo.py one two three

>>> import sys
>>> print(sys.argv)
['demo.py', 'one', 'two', 'three']

argparse模块提供了一种更复杂的机制来处理命令行参数。以下脚本可提取一个或多个文件名,并可选择要显示的行数:

import argparse

parser = argparse.ArgumentParser(
    prog='top',
    description='Show top lines from each file')
parser.add_argument('filenames', nargs='+')
parser.add_argument('-1', '--lines', type=int, default=10)
args = parser.parse_args()
print(args)

当在通过python top.py --lines=5 alpha.txt beta.txt在命令行运行时,该脚本会将args.lines设为5并将args.filenames设为['alpha.txt', 'beta.txt']。

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

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'

6.数学

math模块提供对浮点数学的底层C库函数的访问:

>>> import math
>>> math.cos(math.pi / 4)
0.7071067811865476
>>> math.log(1024, 2)
10.0

random模块提供了进行随机选择的工具:

>>> import random
>>> random.choice(['apple', 'pear', 'banana'])
'banana'
>>> random.sample(range(100), 10)  # sampling without replacement
[67, 18, 31, 81, 34, 77, 23, 3, 28, 7]
>>> random.random() # random float
0.637671586618542
>>> random.randrange(7) # random integer chosen from range(7)
4

statisstics模块计算数值数据的基本统计属性(均值,中位数,方差等):

>>> import statistics
>>> data = [1.23, 1.25, 1.89, 0.23, 4.32, 1.23]
>>> statistics.mean(data)
1.6916666666666667
>>> statistics.median(data)
1.24
>>> statistics.variance(data)
1.9410566666666669

7.互联网访问

有许多模块可用于访问互联网和处理互联网协议。其中两个最简单的urllib.request用于从URL检索数据,以及smtplib用于发送邮件:

>>> from urllib.request import urlopen
>>> with urlopen('http://worldtimeapi.org/api/timezone/etc/UTC.txt') as response:
...     for line in response:
...         line = line.decode()    # Convert bytes to a str
...         if line.startswith('datetime'):
...             print(line.rstrip()) # Remove trailing newline
...
datetime: 2022-05-13T08:24:13.332123+00:00

>>> 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上运行的邮件服务器。)

8.日期和时间

datetime模块提供了以简单和复杂的方式操作日期和时间的类。虽然支持日期和时间算法,但实现的重点是有效的成员提取以进行输出格式化和操作。该模块还支持可感知时区的对象。

>>> # dates are easily constructed and formatted
>>> from datetime import date
>>> now= date.today()
>>> now
datetime.date(2022, 5, 13)
>>> now.strftime("%m-%d-%y. %d %b %Y is a %A on the %d day of %B.")
'05-13-22. 13 May 2022 is a Friday on the 13 day of May.'
>>> # dates support calendar arithmetic
>>> birthday = date(1996, 5, 26)
>>> age = now - birthday
>>> age.days
9483

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.性能测量

一些python用户对了解同一问题的不同方法的相对性能产生了浓厚的兴趣。python提供了一种可以立即回答这些问题的测量工具。

例如,元组封包和拆包功能相比传统的交换参数可能更具吸引力。timeit模块可以快速演示在运行效率方面一定的优势:

>>> from timeit import Timer
>>> Timer('t=a; a=b; b=t', 'a=1; b=2').timeit()
0.07341450000240002
>>> Timer('a, b = b, a', 'a=1; b=2').timeit()
0.056284700011019595

与timeit的精细粒度级别相反,profile和pstats模块提供了用在较大的代码块中识别时间关键部分的工具。

11.质量控制

开发高质量软件的一种方法是在开发过程中为每个函数编写测试,并在开发过程中经常运行这行测试。doctest模块提供了一个工具,用于扫描模块并验证程序文档字符串中嵌入的测试。测试构造就像将典型调用以及其结果剪切并粘贴到文档字符串一样简单。这通过向用户提示示例来改进文档,并且它允许doctest模块确保代码保持对文档的真实:

def average(values):
    """Computes the arithmetic mean of a list of numbers."""
    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.格式化输出

reprlib模块提供了一个定制化版本repr()函数,用于缩略显示大型或深层嵌套的容器对象:

>>> import reprlib
>>> reprlib.repr(set('supercalifragilisticexpialidoicous'))
"{'a', 'c', 'd', 'e', 'f', 'g', ...}"

pprint模块提供了更加复杂的打印控制,其输出的内置对象和用户自定义对象能够被解释器直接读取。当输出结果过长而需要折行时,“美化输出机制”会添加换行符合缩进,以更清楚地展示数据结构:

>>> import pprint
>>> t = [[[['black','cyan'], 'white', ['green', 'red']], [['magenta',
...     'yellow'], 'blue']]]
>>> pprint.pprint(t, width=30)
[[[['black', 'cyan'],
   'white',
   ['green', 'red']],
  [['magenta', 'yellow'],
   'blue']]]

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 separte 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 separte the wrapped lines.

locale模块处理与特定地域文化相关的数据格式。locale模块的fromat函数包含一个grouping属性,可直接将数据格式化为带有组分隔符的样式:

>>> 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)
<stdin>:1: DeprecationWarning: This method will be removed in a future version of Python. Use 'locale.format_string()' instead.
'1,234,567'
>>> locale.format_string("%s%.*f", (conv['currency_symbol'],
...                      conv['frac_digits'], x), grouping=True)
'$1,234,567.80'

11.模板

string模块包含一个通用的Template类,具有适用于最终用户的简化语法。它允许用户在不更改应用逻辑的情况下定制自己的应用。

上述格式化操作是通过占位符实现的,占位符由$加上合法的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.'

如果在字典或关键字参数中未提供某个占位符的值,那么substitute()方法将抛出KeyError。对于邮件合并类型的应用,用户提供的数据有可能是不完整的,此时使用safe_substitue()方法更加合适——如果数据缺失,它会直接将占位符原样保留。

>>> t = Template('Return the $item to $owner.')
>>> d = dict(item='unladen swallow')
>>> t.substitute(d)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "E:\Python\Python3\lib\string.py", line 121, in substitute
    return self.pattern.sub(convert, self.template)
  File "E:\Python\Python3\lib\string.py", line 114, in convert
    return str(mapping[named])
KeyError: 'owner'
>>> t.safe_substitute(d)
'Return the unladen swallow to $owner.'

Template的子类可以自定义分隔符。例如,以下是某个照片浏览器的批量重命名功能,采用了百分号作为日期、照片序号和照片格式的占位符:

>>> import time, os.path
>>> photofiles = ['img_1074.jpg', 'img_1075.jpb', 'img_1076.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_1075.jpb—>Ashley_1.jpb
img_1076.jpg—>Ashley_2.jpg

模板的另一个应用是将程序逻辑与多样的格式化输出细节分离开来。这使得对XML文件、纯文本报表和HTML网格报表使用自定义模板称为可能。

12.使用二进制数据记录格式

struct模块提供了pack()和unpack()函数,用于处理不定长度的二进制记录格式。下面的例子展示了在不适用zipfile模块的情况下,如何循环遍历一个ZIP文件的所有头信息。Pack代码“H”和“I”分别代表两字节和四字节无符号整数。“<”代表它们是标准尺寸的小端字节序:

import struct

with open('fibo.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('<IIIHH', 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

13.多线程

线程是一种对于非顺序依赖的多个任务进行解耦的技术。多线程可以提高应用的响应效率,当接收用户输入的同时,保持其他任务在后台运行。一个有关的应用场景是,将I/O和计算运行在两个并行的线程中。

以下代码展示了高阶的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 f:", 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.")

14.日志记录

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

默认情况下,information和debugging消息被压制,输出会发送到标准错误流。其他输出选项包括将消息转发到电子文件,数据报,套接字或HTTP服务器。新的过滤器可以根据消息优先级选择不同的路由器方式:DEBUG,INFO,WARNING,ERROR,和CRITICAL。

日志系统可以直接从python配置,也可以从用户配置文件加载,以便自定义日志记录而无需更改应用程序。

15.弱引用

python会自动进行内存管理(对大多数对象进行引用计数并使用garbage collection来清楚循环引用)。当某个对象的最后一个引用被移除后不久就会释放其所占用的内存。

此方式对大多数应用来说都使用,但偶尔也必须在对象持续被其他对象所使用时跟踪它们。不幸的是,跟踪它们将穿件一个会令其永久化的引用。weakref模块提供的工具可以不必创建应用就能跟踪对象。当对象不再需要时,它将自动从一个弱引用列表中移除,并未弱引用对象触发一个回调。典型应用包括对创建开销较大的对象进行缓存:

>>> import logging
>>> logging.debug('Debugging information')
>>> 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 "<stdin>", line 1, in <module>
  File "E:\Python\Python3\lib\weakref.py", line 137, in __getitem__
    o = self.data[key]()
KeyError: 'primary'

16.用于操作列表的工具

许多对于数据结构的需求可以通过内置列表类型来满足。array模块提供了一种array()对象,它类似列表,但只能存储类型一致的数据且存储密度集更高。小面的例子演示了一个以两个字节为存储单元的无符号二进制数值的数组(类型码为“H”),而对于普通列表来说,每个条目存储为标准Python的int对象通常要占用16个字节。

>>> from array import array
>>> a = array('H', [4000, 10, 700, 2330])
>>> sum(a)
7040
>>> a[1:3]
array('H', [10, 700])

Collections模块提供了一种deque()对象,它类似与列表,但从左端添加和弹出的速度较快,而在中间查找的速度较慢。此种对象适用于实现队列和广度优先树搜索:

>>> from collections import deque
>>> d = deque(['task1', 'task2', 'task3'])
>>> d.append('task4')
>>> print('Handing', d.popleft())
Handing task1

在替代的列表实现以外,标准库也提供了其他工具,例如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')]

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]

17.十进制浮点运算

decimal模块提供了一种Decimal数据类型用于十进制浮点运算。相比内置float二进制浮点实现,该类特别适用于

  • 财务应用和其他需要精确十进制表示的用途
  • 控制精度
  • 控制四色五入以满足法律或监管要求
  • 跟踪有效小数位
  • 用户期望结果与手工完成的计算向匹配的应用程序

 Decimal表示的结果会保留尾部的零,并根据具有两个有效位的被乘数自动退出四个有效位。Decimal可以模拟手工运算来避免当二进制浮点数无法精确表示十进制数时会导致的问题。

精确表示特性使得Decimal类能够执行对于二进制浮点数来说不适用的模运算和相等性检测:

>>> from decimal import *
>>> 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模块提供了运算所需要的足够精度:

>>> getcontext().prec = 36
>>> Decimal(1) / Decimal(7)
Decimal('0.142857142857142857142857142857142857')

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值