读书笔记 - 《Intermediate Python》

刚刚读完 《Intermediate Python》中译《Python 进阶》)。部分知识在看书前已经知道,在这里将新了解到的内容总结一下。方便未来的查阅。其中涉及到的内容有:

  • Filter
  • Reduce
  • Coroutine
  • __slots__
  • namedtuple
  • One-liners

filter(function, iterable)

filter 被用于返回符合条件的元素。比如我们要列表中全部的正数,使用filter只需要一行代码。

1
2
all_elements = list(range(-5, 5))
positive_elements = filter(lambda x: x>0, all_elements)

其中的 lambda 代码可以被替换为 function。例如,

1
2
3
def is_positive(n):
return n > 0
positive_elements = filter(is_positive, all_elements)

reduce(function, iterable)

reduce 来自于 functools。中文实在不知怎么翻译,直接贴英文解释过来。

Apply function of two arguments cumulatively to the items of iterable, from left to right, so as to reduce the iterable to a single value.

用一个累加的例子来解释,

1
2
3
from functools import reduce
nums = [1,2,3,4]
agg_value = reduce(lambda x,y: x+y, nums)

其中reduce 部分的数学表达可以写为 (((1+2)+3)+4)。

目前没有想到什么特别适合的用例,暂且记下。

Coroutine (协程)

里面介绍的基于生成器的协程的支持 已弃用 并计划在 Python 3.10 中移除。

__slots__

书里只介绍了可以节省内存空间,根据 StackOverflow 上的回答,这个解释并不全面。使用__slots__ 有以下特点:

  • 节省内存空间 [1]
  • 加快访问 attribute 的速度 [1]
  • 限制 instance 可新增的 attribute [2]

这里我们使用 macBook Pro M1 测试访问速度的代码。可以看到使用 __slots__ 后,实例化类与访问attribute 的速度明显加快。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
class NoSlots():
def __init__(self):
self.foo = None


class HasSlots():
__slots__ = ("foo")
def __init__(self):
self.foo = None

def create_no_slots():
return NoSlots()

def create_has_slots():
return HasSlots()

from timeit import timeit

# Test speed of creating object
timeit(create_has_slots, number=10000000)
#output: 1.5809720420002122
timeit(create_no_slots, number=10000000)
#output: 1.921864375000041

# Test speed of accessing attribute
no_slots_obj = NoSlots()
has_slots_obj = HasSlots()

def access_no_slots():
return no_slots_obj.foo

def access_has_slots():
return has_slots_obj.foo

timeit(access_no_slots, number=1000000)
#output: 0.10885849999976926
timeit(access_no_slots, number=10000000)
#output: 0.731041125000047

namedtuple(typename, field_names)

collections.namedtuple提供了一种更可读的tuple,它保留了tuple immutable的属性,同时我们可以通过名称而不用整数索引来访问数据。 示例如下:

1
2
3
4
from collections import namedtuple

Animal = namedtuple('Animal', 'name age type')
perry = Animal(name="perry", age=31, type="cat")

官方文档 中说该数据类型适用于读取来源于 csv/sqlite3 模块返回的 tuple。除了这两个,目前没想到很好的应用场景。

One-liners

这里面的内容很杂,这里收录几个我觉得比较有用的。

简易Web Server

1
2
# Python 3
pytho3 -m http.server

漂亮的打印

使用 pprint

1
from pprint import pprint

脚本性能分析

这能帮助定位脚本中的性能瓶颈

1
python -m cProfile my_script.py

列表辗平

1
2
3
a_list = [[1, 2], [3, 4], [5, 6]]
print(list(itertools.chain.from_iterable(a_list)))
# Output: [1, 2, 3, 4, 5, 6]

[1] StackOverflow: Usage of __slots__?]

[2] 廖雪峰的官方网站: 使用__slots__

Recommended Posts