跟着董伟明大佬的书了解了解 python常用的类库

一、errno

在日常开发中经常需要捕获各种异常,做特殊处理。举个例子:

    os.kill(12345,0)

输出

Traceback (most recent call last):
  File "/Users/zhangkun/Documents/GitHub/geektime/test.py", line 4, in <module>
    os.kill(12345,0)
ProcessLookupError: [Errno 3] No such process

信号为0,表示这只是检查PID的有效性。根据提示,这是一个“Nosuchprocess”类型的错误,注意方括号中的“Errno3”,这其实是Python内置的错误系统提供的编号:

In:os.strerror(3)
Out:'Nosuchprocess'

还可以使用errno模块找到对应的错误类型,更精准地做异常处理(errno_example.py):

import os
import errno


def listdir(dirname):
    try:
        os.listdir(dirname)
    except OSError as e:
        error = e.errno
    if error == errno.ENOENT:
        print('no such file or directory')
    elif error == errno.EACCES:
        print('Permission denied')
    elif error == errno.ENOSPC:
        print('No space left on device')
    else:
        print(e.strerror)


for filename in ['/no/such/dir', '/root', '/home/ubuntu']:
    listdir(filename)

通过对比异常对象的errno属性值就能知道异常类型。

二、subprocess

subprocess模块用来取代如下模块和函数:

os.system
os.spawn*
os.popen*
popen2.*
commands.*

1.call:执行系统命令,可以替代os.system。call只返回命令的返回值。

In:subprocess.call('ls-l/tmp/mongodb27017.sock',shell=True)
srwx------1 mongodbmongodb0May1012:24/tmp/mongodb27017.sock
Out:0
In:subprocess.call('exit1',shell=True)
Out:1

通常由于安全问题,不建议使用shell=True,可以把命令拆分成列表

In:subprocess.call(['ls','/tmp/mongodb27017.sock'],shell=False)
/tmp/mongodb27017.sock
Out:0

拆分命令最简单的方法是使用shlex模块:

In:shlex.split('ls/tmp/mongodb27017.sock')
Out:['ls','/tmp/mongodb27017.sock']

2.check_call:添加了错误处理的执行系统命令方法。当执行call方法的返回值不为0,就会抛出CalledProcessError异常。

董伟明. Python Web开发实战 (Kindle Locations 7512-7513). Kindle Edition.

3.Popen:一个用来执行子进程的类,通过communicate方法获得执行结果:

董伟明. Python Web开发实战 (Kindle Locations 7517-7518). Kindle Edition.

4. 4.check_output:在Python2.7和Python3中都可用,它比Popen更简单地获得输出,但是需要执行的返回值为0,否则仍然抛出CalledProcessError异常。

董伟明. Python Web开发实战 (Kindle Locations 7523-7525). Kindle Edition.
在出现错误的时候,可以额外地执行exit0,就能正常获得输出:

董伟明. Python Web开发实战 (Kindle Location 7527). Kindle Edition.

三、contextlib

写Python代码的时候经常将一系列操作放在一个语句块中,Python2.5加入了with语法,实现上下文管理功能,这让代码的可读性更强并且错误更少。最常见的例子就是open,如果不使用with,使用open时会是这样

import threading

lock = threading.Lock()

lock.acquire()
my_list = []
item = 1
try:
    my_list.append(item)
finally:
    lock.release()

如果使用with就会非常简单

with lock:
    my_list.append(item)

创建上下文管理器实际就是创建一个类,添加__enter__和__exit__方法。看看threading.Lock的上下文管理功能是怎么实现的:

import threading

class LockContext(object):
    def __init__(self):
        print('__init__')
        self.lock=threading.Lock()

    def __enter__(self):
        print('__enter__')
        self.lock.acquire()
        return self

    def __exit__(self, exc_type, exc_val, exc_tb):
        print('__exit__')
        self.lock.release()

with LockContext():
    print('in the context')

输出:

__init__
__enter__
in the context
__exit__

上面的例子比较简单,在执行self.__enter__的时候没有传递参数。下面我们来实现open的上下文管理功能:

董伟明. Python Web开发实战 (Kindle Locations 7550-7551). Kindle Edition.自定义上下文管理器确实很方便,但是Python标准库还提供了更易用的上下文管理器工具模块contextlib,它是通过生成器实现的,我们不必再创建类以及__enter__和__exit__这两个特殊的方法:

from contextlib import contextmanager

@contextmanager
def make_open_context(filename,mode):
    fp = open(filename,mode)
    try:
        yield fp
    finally:
        fp.close()

with make_open_context('/tmp/a','a') as f:
    f.write('hello world')

yield关键词把上下文分割成两部分:yield之前就是__init__中的代码块;yield之后其实就是__exit__中的代码块;yield生成的值会绑定到with语句as子句中的变量(如果没有生成,也就没有as字句)。

董伟明. Python Web开发实战 (Kindle Locations 7564-7565). Kindle Edition.

四、glob

glob用来匹配UNIX风格的路径名字的模块,它支持“”、“?”、“[]”这三种通配符,“”代表0个或多个字符,“?”代表一个字符,“[]”匹配指定范围内的字符,例如[09]匹配数字。我们先创建一个目录,目录中包含如下文件:

董伟明. Python Web开发实战 (Kindle Locations 7575-7577). Kindle Edition.在这里插入图片描述

五、operator

operator是一个内建操作的函数式接口。举个例子,如果想对列表的值求和,可以使用sum,但是如果要相乘呢?其实可以结合reduce和operator模块来实现:

董伟明. Python Web开发实战 (Kindle Locations 7583-7584). Kindle Edition.
operator模块还提供了非常有用的itemgetter、attrgetter和methodcaller方法。

  1. itemgetter。通过被求值对象的__getitem__方法获得符合的条目:

董伟明. Python Web开发实战 (Kindle Locations 7591-7592). Kindle Edition.
另一个使用itemgetter的场景是排序:

董伟明. Python Web开发实战 (Kindle Locations 7594-7595). Kindle Edition.在这里插入图片描述

2.attrgetter。attrgetter根据被求值对象的属性获得符合条件的结果:

董伟明. Python Web开发实战 (Kindle Location 7599). Kindle Edition.

再简单一点:

reduce(getattr,'b,c,d'.split('.'),a)

而使用attrgetter就很简洁:

operator.attrgetter('b.c.d')(a)

3.methodcaller。methodcaller将调用被求值对象的方法:

董伟明. Python Web开发实战 (Kindle Locations 7607-7608). Kindle Edition.

六、functools

functools模块中包含了一系列操作其他函数的工具。
1.partial。partial可以重新定义函数签名,也就是在执行函数之前把一些参数预先传给函数,待执行时传入的参数数量会减少。

董伟明. Python Web开发实战 (Kindle Locations 7610-7612). Kindle Edition.

2.wraps。把被封装函数的__name__、module、__doc__和__dict__复制到封装函数中,这样在未来排错或者函数自省的时候能够获得正确的源函数的对应属性,所以使用wraps是一个好习惯。我们先看不使用wraps的例子:

董伟明. Python Web开发实战 (Kindle Locations 7619-7620). Kindle Edition.

3.total_ordering。对比自定义对象需要添加__lt__、legtge__和__eq__等方法,如果使用total_ordering,只需要定义__eq,以及定义__lt__、legt、__ge__四种方法之一就可以了:

董伟明. Python Web开发实战 (Kindle Locations 7632-7633). Kindle Edition.

4.cmp_to_key。Python2的sorted函数除了通过指定key参数的值作为依据来排序,还支持cmp参数:

董伟明. Python Web开发实战 (Kindle Locations 7639-7640). Kindle Edition.

除了兼容Python3的sorted,还可以把比较函数转换后用于min、max、heapq.nlargest、heapq.nsmallest、itertools.groupby等支持key参数的函数上。

七、collections

collections包含5个高性能的计算器工具

1. Counter 一个方便、快速计算的计时器工具

在这里插入图片描述
可以直接list()将Counter类型对象转为列表

2.deque:一个双端队列,能够在队列两端添加或删除队列元素。它支持线程安全,能够有效利用内存。无论从队列的哪端入队和出队,性能都能够接近于O(1)。

董伟明. Python Web开发实战 (Kindle Locations 7656-7658). Kindle Edition.

在这里插入图片描述

3.defaultdict。defaultdict简化了处理不存在的键的场景。如果不使用defaultdict,对一个单词的计数要这样实现:

董伟明. Python Web开发实战 (Kindle Locations 7669-7670). Kindle Edition.

defaultdict参数就是值的类型,还可以使用自定义类型。下面演示一个插入后自动排序的自定义列表类型:

董伟明. Python Web开发实战 (Kindle Locations 7676-7677). Kindle Edition. 在这里插入图片描述

4.OrderedDict。Python的dict结构是无序的:

董伟明. Python Web开发实战 (Kindle Locations 7686-7687). Kindle Edition.

5.namedtuple。namedtuple能创建可以通过属性访问元素内容的扩展元组。使用namedtuple能创建更健壮、可读性更好的代码。

假设不使用namedtuple,查询数据库获得如下一条记录:

董伟明. Python Web开发实战 (Kindle Location 7694). Kindle Edition.

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值