python3-cookbook中每个小节以问题、解决方案和讨论三个部分探讨了Python3在某类问题中的最优解决方式,或者说是探讨Python3本身的数据结构、函数、类等特性在某类问题上如何更好地使用。这本书对于加深Python3的理解和提升Python编程能力的都有显著帮助,特别是对怎么提高Python程序的性能会有很好的帮助,如果有时间的话强烈建议看一下。
本文为学习笔记,文中的内容只是根据自己的工作需要和平时使用写了书中的部分内容,并且文中的示例代码大多直接贴的原文代码,当然,代码多数都在Python3.6的环境上都验证过了的。不同领域的编程关注点也会有所不同,有兴趣的可以去看全文。
python3-cookbook:https://python3-cookbook.readthedocs.io/zh_CN/latest/index.html

 

SRE实战 互联网时代守护先锋,助力企业售后服务体系运筹帷幄!一键直达领取阿里云限量特价优惠。

7.2 只接受关键字参数的函数

有时候为了代码可读性或者其他原因,我们需要在使用函数的时候强制要求调用者使用关键字参数,这时候只需要在某个*参数或单个*后面定义关键字参数即可。

def print_ax(a, x):
    print(a, x)


def print_x(a, *, x):
    print(a, x)


print_ax(111, 222)
# 如果这样写就会报错:print_x(111, 222)
print_x(111, x=222)

 

 

7.7 匿名函数捕获变量值

lambda表达式的参数值是在运行时绑定的,而不是定义时绑定的,这跟def定义参数默认值是不同的,如果需要lambda表达式在定义时就绑定值,可以使用参数默认值的写法。

>>> x = 10
>>> a = lambda y: x + y
>>> x = 20
>>> b = lambda y: x + y
>>> # 下面两个执行结果是一样的
>>> a(10)
30
>>> b(10)
30
>>> x = 30
>>> a(10)
40
>>> b(10)
40
>>> # 使用参数默认值的方式
>>> a = lambda y, x=x: x + y
>>> b = lambda y, x=x: x + y
>>> a(10)
40
>>> b(10)
40
>>> 

 

 

7.8 减少可调用对象的参数个数

当调用某个函数的时候可能你并不需要传入全部参数值,或者只能传入部分参数值,就可以使用functools.partial()。

用法示例:

>>> from functools import partial
>>> def spam(a, b, c, d):
    print(a, b, c, d)

    
>>> s1 = partial(spam, 1)  # a = 1
>>> s1(2, 3, 4)
1 2 3 4
>>> s2 = partial(spam, d=42) # d = 42
>>> s2(1, 2, 3)
1 2 3 42
>>> s3 = partial(spam, 1, 2, d=42) # a = 1, b = 2, d = 42
>>> s3(3)
1 2 3 42
>>> 

排序使用示例:

"""将列表中的点根据距离基点的距离进行排序"""
import math
from functools import partial

# 基点
pt = (4, 3)
points = [(1, 2), (3, 4), (5, 6), (7, 8)]


def distance(p1, p2):
    """返回两个点之间的距离"""
    x1, y1 = p1
    x2, y2 = p2
    return math.hypot(x2 - x1, y2 - y1)


points.sort(key=partial(distance, pt))
print(points)  # [(3, 4), (1, 2), (5, 6), (7, 8)]

回调函数使用示例:

import logging
from multiprocessing import Pool
from functools import partial


def output_result(result, log=None):
    if log is not None:
        log.debug('Got: %r', result)


def add(x, y):
    return x + y


if __name__ == '__main__':
    # logging模块用于打印日志
    logging.basicConfig(level=logging.DEBUG)
    log = logging.getLogger('test')

    # 异步调用另一个函数,并将log对象传入进去
    p = Pool()
    p.apply_async(add, (3, 4), callback=partial(output_result, log=log))
    p.close()
    p.join()

 

扫码关注我们
微信号:SRE实战
拒绝背锅 运筹帷幄