第十二课时之标准库浏览II

11.标准库浏览II

11.1输出格式

reprlib 模块为大型的或深度嵌套的容器缩写显示提供了 :repr() 函数的一个定制版本:

>>> import reprlib
>>> reprlib.repr(set(‘supercalifragilisticexpialidocious‘))
"set([‘a‘, ‘c‘, ‘d‘, ‘e‘, ‘f‘, ‘g‘, ...])"

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‘]]]

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.

locale 模块按访问预定好的国家信息数据库。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‘

11.2模板

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_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.‘

模板子类可以指定一个自定义分隔符。例如,图像查看器的批量重命名工具可能选择使用百分号作为占位符,像当前日期,图片序列号或文件格式:

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

模板的另一个应用是把多样的输出格式细节从程序逻辑中分类出来。这便使得 XML 文件,纯文本报表和 HTML WEB 报表定制模板成为可能。

11.3使用二进制数据记录布局

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

11.4多线程

线程是一个分离无顺序依赖关系任务的技术。在某些任务运行于后台的时候应用程序会变得迟缓,线程可以提升其速度。一个有关的用途是在 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 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.‘)

多线程应用程序的主要挑战是协调线程,诸如线程间共享数据或其它资源。为了达到那个目的,线程模块提供了许多同步化的原生支持,包括:锁,事件,条件变量和信号灯。

尽管这些工具很强大,微小的设计错误也可能造成难以挽回的故障。因此,任务协调的首选方法是把对一个资源的所有访问集中在一个单独的线程中,然后使用 queue 模块用那个线程服务其他线程的请求。为内部线程通信和协调而使用 Queue 对象的应用程序更易于设计,更可读,并且更可靠。  

11.5日志

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

默认情况下捕获信息和调试消息并将输出发送到标准错误流。其它可选的路由信息方式通过 email,数据报文,socket 或者 HTTP Server。基于消息属性,新的过滤器可以选择不同的路由: DEBUG, INFO, WARNING, ERROR 和 CRITICAL 。

日志系统可以直接在 Python 代码中定制,也可以不经过应用程序直接在一个用户可编辑的配置文件中加载。

11.6弱引用

Python 自动进行内存管理(对大多数的对象进行引用计数和垃圾回收—— 垃圾回收 ——以循环利用)在最后一个引用消失后,内存会很快释放。

这个工作方式对大多数应用程序工作良好,但是偶尔会需要跟踪对象来做一些事。不幸的是,仅仅为跟踪它们创建引用也会使其长期存在。 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 "<stdin>", line 1, in <module>
    d[‘primary‘]                # entry was automatically removed
  File "C:/python34/lib/weakref.py", line 46, in __getitem__
    o = self.data[key]()
KeyError: ‘primary‘

11.7列表工具

很多数据结构可能会用到内置列表类型。然而,有时可能需要不同性能代价的实现。

array 模块提供了一个类似列表的 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])

collections 模块提供了类似列表的 deque() 对象,它从左边添加(append)和弹出(pop)更快,但是在内部查询更慢。这些对象更适用于队列实现和广度优先的树搜索:  

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

除了链表的替代实现,该库还提供了 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 提供了基于正规链表的堆实现。最小的值总是保持在 0 点。这在希望循环访问最小元素但是不想执行完整堆排序的时候非常有用:  

>>> 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]

11.8十进制浮点数算法

decimal 模块提供了一个 Decimal 数据类型用于浮点数计算。相比内置的二进制浮点数实现 float,这个类型有助于

  • 金融应用和其它需要精确十进制表达的场合,
  • 控制精度,
  • 控制舍入以适应法律或者规定要求,
  • 确保十进制数位精度,

    或者

  • 用户希望计算结果与手算相符的场合。

例如,计算 70 分电话费的 5% 税计算,十进制浮点数和二进制浮点数计算结果的差别如下。如果在分值上舍入,这个差别就很重要了:

>>> from decimal import *
>>> round(Decimal(‘0.70‘) * Decimal(‘1.05‘), 2)
Decimal(‘0.74‘)
>>> round(.70 * 1.05, 2)
0.73

Decimal 的结果总是保有结尾的 0,自动从两位精度延伸到4位。Decimal 重现了手工的数学运算,这就确保了二进制浮点数无法精确保有的数据精度。

高精度使 Decimal 可以执行二进制浮点数无法进行的模运算和等值测试:

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

  

  

  

  

  

  

  

  

  

  

  

  

  

原文地址:https://www.cnblogs.com/LQ-Hacker/p/manuals-12.html

时间: 2024-10-24 03:30:58

第十二课时之标准库浏览II的相关文章

Golang中使用log(二):Golang 标准库log的实现

前一篇文章我们看到了Golang标准库中log模块的使用,那么它是如何实现的呢?下面我从log.Logger开始逐步分析其实现. 其源码可以参考官方地址 1.Logger结构 首先来看下类型Logger的定义: type Logger struct { mu sync.Mutex // ensures atomic writes; protects the following fields prefix string // prefix to write at beginning of each

C++ Primer 第四版读书笔记(二)之标准库类型

C++定义了一个内容丰富的抽象数据类型标准库,其中最重要的标准库类型是string和vector,它们分别定义了大小可变的字符串和集合.string和vector往往将迭代器用作配套类型,用于访问string中的字符,或者vector中的元素. 另一种标准库类型为bitset,提供了一种抽象方法来操作位的集合. string类型支持长度可变的字符串,vector用于保存一组指定类型的对象. bitset类标准库类型提供了更方便和合理有效的语言级的抽象设施.通过这个类可以把某个值当作位的集合来处理

雷观(十二):构建基础库,提升研发效率

观点:IT之所以迅速普及,进入到每个人的生活.一方面是由于,IT相关技术产品,给每个人带来了丰富的虚拟世界和娱乐生活.另一方面,它大大提升了大部分行业的生产效率.社会生产力的发展方向,就是时代的发展方向.   程序员等IT技术人员,在IT届的地位,就像IT在社会生活中的地位:不可或缺.普遍存在.生产力的关键. 作为一名自学6年多的程序员,对技术的追求从未曾放弃.但我也终究意识到,纯粹的技术无法带我到达理想境界,而生产力的提高才可以把我从繁杂的基础工作中解脱出来,可以把我带向幸福美好的生活中. 与

C#编程(六十二)---------LINQ标准的查询操作符

LINQ标准的查询操作符 首先我们来看一下LINQ的操作符,可根据查询操作符的操作"类型"进行分类,如把它们分成投影,限制,排序,联接,分组,串联,聚合,集合,生成,转换,元素,相等,量词,分割等. 类型 操作符名称 投影操作符 Select,SelectMany 限制操作符 Where 排序操作符 OrderBy,OrderByDescending,ThenBy,ThenByDescending,Reverse 联接操作符 Join,GroupJoin 分组操作符 GroupBy 串

linux-第十二课时笔记-[FTP服务器搭建]-[本地FTP]-[02]

FTP本地服务器搭建 yum安装vsftpd服务: [[email protected] ~]# yum -y install vsftpd 创建本地两个用户: [[email protected] ~]# useradd test1 [[email protected] ~]# useradd test2 [[email protected] ~]# echo "123" | passwd --stdin test1 &> /dev/null [[email prote

linux-第十二课时笔记-[FTP服务器搭建]-[虚拟用户FTP]-[03]

FTP虚拟用户服务器搭建: 创捷一个账号列表: [[email protected] vsftpd]# echo -e "msl23\n123\nbenet\n123" >> vusers.list [[email protected] vsftpd]# cat vusers.list msl23 123 benet 123 [[email protected] vsftpd]# 使用db_load把别表变为数据库: [[email protected] vsftpd]#

C++ 第十二课 其它标准C函数

abort() 停止程序执行 assert() 当表达式非真,停止程序执行 atexit() 当程序退出执行设定的程序 bsearch() 执行折半查找 exit() 停止程序执行 getenv() 获取指定环境变量的值 longjmp() 从设定点执行程序 qsort() 执行快速排序 raise() 向程序发送信号 rand() 返回一个随机数 setjmp() 设置程序执行点 signal() 将某函数设置成一个信号句柄 srand() 初始化随机数发生源 system() 执行系统调用

第十二课时:时序分析中的基本概念和术语

经典的时序分析模型 1. 建立时间边缘和保持时间边缘 reg a源端寄存器 reg b目的端寄存器,有共同的时钟源 2. 4种时序路径 PPT1 第四类是纯组合的路径 前三类是同一类 PPT2 3. 数据到达时间 PPT1 Tdata是布线延时h和逻辑延时和逻辑延迟 PPT2 捕获沿 建立时间要求 4. 保持时间的要求 数据到达之后至少存在Th,新的数据不能太早的到 5. 余量计算 PPT1 保持时间的余量 新的数据不能太早的到达,否则破坏了 PPT2 余量的计算 对于保持时间到达时间是下一个数

Go语言开发(十二)、Go语言常用标准库二

Go语言开发(十二).Go语言常用标准库二 一.os 1.os简介 os 包提供了不依赖平台的操作系统函数接口,设计像Unix风格,但错误处理是go风格,当os包使用时,如果失败后返回错误类型而不是错误数量. 2.os常用接口 func Hostname() (name string, err error) // Hostname返回内核提供的主机名 func Environ() []string // Environ返回表示环境变量的格式为"key=value"的字符串的切片拷贝 f