Fluent Python 适用于中级 Pythoner。
以 Python 作为主力编程语言已经 1 年多了,读这本书,希望写的代码可以更加的 Pythonic。
序言部分讲了很重要的一点,Python 最优秀的地方就是其统一性。
Pythonic 体现在使用的 Python Data Model 来表述,其途径主要编写特殊方法 (Special/Magic Method)
扩展阅读:http://zopeinterface.readthedocs.io/en/latest/
#### 1. 案例一:纸牌 nametuple
Card = collections.namedtuple('Card', ['rank', 'suit'])
# Card 是一个类
# 重载到 Cards(object) 的 __init__ , __len__ , __getitem__
# 重载可以之后可以使用 [] 语法 ( [0] [-1] random.choice(cards) [:3] [12::13] for in sorted reversed,sorted(cards, key=calc_score) card in cards ),
# 还可以重载 __setitem__, 之后就可以 shuffle
# 重载 __repr__ , __abs__ , __bool__ , __add__ , __mul__ 可以 repr() abs() bool() + *
obj.__len__()
len()
obj.__
对于内置类型 (list, str , bytearray) 解释器在调用特殊方法的时候调用 C 库,比如 CPython 实现的 len 方法一般直接会调用 PyVarObject C Struct ob_size
特殊方法往往并不是显示调用,而是被隐式调用。比如 init 在 new 中的作用,比如 for item in items 世界上会调用 iter(items), 这也会隐式调用 items.iter() .
一般当大量使用特殊方法的时候,都是在进行元编程。
bool(x) 先调用 x.__bool__() , 如果 x.__bool__() 没有实现,则调用 x.__len__(), 如果为 0 则返回 False
sorted(arr) 可以直接返回 arr,arr.sort() 是排序内部。
特殊方法名 (有操作符)
种类 | 方法名 |
---|---|
String/Bytes | repr , str , format , bytes |
Conversion to number | abs , bool , complex , init , float , hash , index |
Emulating collections | len , getitem , setitem , delitem , contains |
Iteration | iter, reversed , next |
Emulating callables | call |
Context management | enter, exit |
Instance creation & destruction | new , init , del |
Attribute management | getattr , getattribute , setattr , delattr, dir |
Attribute descriptors | get , set ,delete |
Class service | prepare , instancecheck , subclasscheck |
特殊方法名 (无操作符)
种类 | 方法名 |
---|---|
Unary numeric operators | neg , pos , abs |
Rich comparison operators | lt , le , eq , ne , gt , ge |
Arithmetic operators | add ,sub , mul ,truediv ,floordiv ,mod , divmod , pow , round round |
Reversed arithmetic operators | radd , rsub , rmul , rtruediv, rfloordiv , rmod , rdivmod, rpow |
Augmented assignment mathmatic | iadd , isub , imul , itruediv, ifloordiv |
Bitwise operators | invert , lshift , rshift , and , or |
Reversed bitwise operators | rlshift , rrshift , rand , rxor , ror |
Augmented assignment bitwise | ilshift , irshift , iand , ixor , ior |
因为对 不同类型并不是一定调用 __len__ , 对于基本类型查看 c struct 中长度,对于其他类型直接调用 __len__ , 这种区分对待
Strings, lists, byte sequences, arrays, XML elements, and database results share a rich set of common operations including iteration, slicing, sorting, and concatenation.
C 实现的按照 item 是否为同一类型分为:
C 实现按照 item 是否可修改分为:
new_items = [func(a) for item in items]
new_items = [ str(x) for x in range(100) if x % 2 == 0]
new_items = list(map(str,list(filter(lambda x: x % 2 == 0 , list(range(100))))))
# 可写成
new_items = list(map(str,filter(lambda x: x % 2 == 0 , range(100))))
list 往往和 map filter 以及 listcomp 用于创建简单的序列
a, b, *rest = range(5) # (0, 1, [2, 3, 4])
a, b, *rest = range(3) # (0, 1, [2])
a, b, *rest = range(2) # (0, 1, [])
a, *body, c, d = range(5) # (0, [1, 2], 3, 4)
*head, b, c, d = range(5) # ([0, 1], 2, 3, 4)
City = namedtuple('City', 'name country population coordinates')
tokyo = City('Tokyo', 'JP', 36.933, (35.689722, 139.691667))
tokyo.population
tokyo.coordinates
tokyo[1]
City._fields # tuple
为何 Slice 和 Range 会排除 最后一个 Item?
书中讲的太复杂,其实这个和尺子是一个作用,尺子从 0 刻度开始,这样方便丈量。
比如说:
a[i, j] # 调用 a.__getitem__((i, j))
对于不可变类型 赋值 l *= 2 在内存中则是创建了新的两个长度的元祖,然后赋值
而由于字符串则需要注意,str_a += "str b" , 虽然为不可变变量,但并不需要拷贝整个字符串(特殊情况), 但字符串的拼接建议还是"".join()
t = (1, 2, [30, 40])
t[2] += [50, 60]
# 结果为既赋值成功,又报错
# 但 t[2].extend([50, 60]) 可以赋值成功
import dis
dis.dis('s[a] += b') # 可以查看字节码
对于 sort 和 sorted 来说,reverse 代表 desc,key 为单参数用于计算每一个值的结果的函数。
list.sort 直接针对列表排序,并且返回 None(出于编程习惯的问题,直接返回 None 的函数大多是对程序有一定的修改)
import bisect
bisect -> bisect_right
bisect_left
insort -> insort_left
insort_right
# 搜索可以用来划分档次
def grade(score, breakpoints=[60, 70, 80, 90], grades='FDCBA'):
i = bisect.bisect(breakpoints, score)
return grades[i]
[grade(score) for score in [33, 99, 77, 70, 89, 90, 100]] # ['F', 'A', 'C', 'C', 'B', 'A', 'A']
list 是一种 mix-typed 的数据结构,即可以存放不同种类型的数据结构,由此带来的问题自然是性能问题:
当考虑性能的时候,则需要考虑是不是要换一个更好的数据结构:
# Arrays
floats = array('d', (random() for i in range(10**7)))
# NumPy and SciPy
# Deques and Other Queue
本章内容:
Hashable ? 一个 obj 的 hash value 在他生命周期内 hash value 是不变的。一个 frozen set 也是 hashable 的(包括每个子元素).
All of Python’s immutable built-in objects are hashable , except that tuple
如果一个 tuple 是每个子元素都是 hashable 的话,则该 tuple 也是 hashable 的。
# 直接在 dict 上面进行操作
index.setdefault(word, []).append(location)
keyerror 会触发 missing 方法
OrderedDict - 有序字典
ChainMap - 组装多个字典,按照次序搜索
Counter - COUNTER
交差并补
# 1. 交集
s & z
z & s
s &= z
# 2. 差集
s - z
z - s
s -= z
# 3. 并集
s | z
z | s
s |= z
# 4. 补集
s ^ z
z ^ s
s ^= z
# 被包含
e in z
# 子集
s <= z
s => z
- Character Issues
- Byte Essentials
- Basic Encoders/Decoders
- Understanding Encode/Decode Problems
- Handling Text Files
- Normalizng Unicode for Saner Comparisons
- Sorting Unicode Text
- The Unicode Database
- Dual-Mode str and bytes APIs
- Summary
- Further Reading
function is the first-class object
Higher-Order Functions
设计模式
装饰器
callables
function attributes
introspection
parameter annotations
nonlocal declaration
references, mutability, 实例生命周期,定制自己集合类 collections and ABCs, 多继承,重载操作符。
生成器
上下文管理器
协程 (包括 Yield)
concurrency
event-oriented IO asyncio
动态创建类
descriptors
class decorators
metaclasses
- Treating a Function Like an Object
- Higher-Order Functions
- Anonymous Functions
- The Seven Flavors of Callable Objects
- User-Defined Callable Types
- Function Introspection
- From Positional to Keyword-Only Parameters
- Function Annotations
- Packages for Functional Programming
- Summary
- Further Reading
- Refactoring Strategy
- Command
- Summary
- Further Reading
- Decorators 101
- When Python Executes Decorators
- Decorator-Enhanced Strategy Pattern
- Variable Scope Rules
- Closures
- The nonlocal Declaration
- Implementing a Simple Decorator
- Decorators In the Standard Library
- Stacked Decorators
- Parameterized Decorators
- Summary
- Further Reading
reference variable : variable 不是盒子,贴在盒子上的标签。
赋值并非创建 Copy
赋值给一个值并非改变之前绑定的值,而仅仅是重新绑定 rebinding
函数由于参数为 reference, 所以可以修改 mutable 的变量
函数参数不应当初始化为可修改的值。
id 与 == : 内存值 和 值相等
copy 默认是浅拷贝
函数参数是引用
GC 使用的引用计数,通过 weakref.finalize 可以增加 obj 被回收的回调函数
强引用和弱引用,weakref 具体使用场景? https://pymotw.com/3/weakref/
One example is a class that wants to keep track of all its current instances. This can be done with weak references, a low-level mechanism underlying the more useful collections WeakValueDictionary, WeakKey Dictionary, WeakSet, and the finalize function from the weakref module.
公用字符串字面量和小的数的技巧叫做 interning
PS:
在 IPython 中 _ 为某个表达式返回的值
- Weak References
- Tricts Python Plays with Immutables
- Summary
- Further Reading
- Object Representations
- Vector Class Redux
- An Alternative Constructor
- classmethod VS staticmethod
- Formatted Displays
- A Hashable Vector2d
- Private and "Protected" Attributes in Python
- Saving Space with the slots Class Attribute
- Overriding Class Attributes
- Summary
- Further Reading
- Vector: A User-Defined Sequence Type
- Vector Take #1: Vector2d Compatible
- Protocols and Duck Typing
- Vector Take #2: A Sliceable Sequence
- Vector Take #3: Dynamic Attribute Access
- Vector Take #4: Hashing and a Faster ==
- Vector Take #5: Formatting
- Summary
- Further Reading
- Interfaces and Protocols in Python Culture
- Python Digs Sequences
- Monkey-Patching to Implement a Protocol at Runtime
- Alex Martelli's Waterfowl
- Subclassing an ABC
- ABCs in the Standard Library
- Defining and Using an ABC
- How the Tombola Subclasses Were Tested
- Usage of register in Practice
- Geese Can Behave as Ducks
- Chapter Summary
- Further Reading
- Subclassing Built-In Types Is Tricty
- Multiple Inheritance and Method Resolution Order
- Multiple Inheritance in the Real World
- Coping with Multiple Inheritance
- A Modern Example: Mixins in Django Generic Views
- Chapter Summary
- Further Reading
依据我的经验。除非特别适合,比如说矩阵相加,否则不要进行操作符重载。 因为 加减乘除之类的操作符本身就容易有二义性。
- Sentence Take #1 : A Sequence of Words Iterables VS Iterators
- Iterables Versus Itertors
- Sentence Take #2 : A Classic Iterator
- Sentence Take #3 : A Generator Function
- Sentence Take #4 : A Lazy Implementation
- Sentence Take #5 : A Generator Expression
- Generator Expressions : When to Use Them
- Another Example : Arithmetic Progression Generator
- Generator Functions in the Standard Library
- New Syntax In Python 3.3 : yield from
- Iterable Reducing Functions
- A Closer Look at the iter Function
- Case Study : Generators in a Databse Conversion Utility
- Generators as Coroutines
- Chapter Summary
- Further Reading
- Do This , Then That: else Blocks Beyond if
- Context Managers and with Blocks
- The contextlib Utilities
- Using @contextmanager
- Chapter Summary
- Further Reading
- How Coroutines Evolved from Generators
- Basic Behavior of a Generator Used as a Coroutine
- Example: Coroutine to Compute a Running Average
- Decorators for Conroutine Priming
- Coroutine Termination and Exception Handing
- Returning a Value from a Coroutine
- Using Yield from
- The Meaning of yield from
- Use Case: Coroutines for Discrete Event Simulation
- Chapter Summary
- Further Reading
- e.g. Web Downloads in Three Styles
- Blocking I/O and the GIL
- Launching Processes with concurrent.futures
- Experimenting with Executor.map
- Downloads with Progress Display and Error Handling
- Chapter Summary
- Further Reading
- Thread VS Coroutine : A Comparison
- Downloading with asyncio and aiohttp
- Running Circling Around Blocking Calls
- Enhancing the asyncio downloader Script
- From Callbacks to Futures and Coroutines
- Writing asyncio Servers
- Chapter Summary
- Further Reading
- Data Wrangling with Dynamic Attributes
- Using a Property for Attribute Validation
- A Proper Look at Properties
- Coding a Property Factory
- Handling Attribute Deletion
- Essential Attributes and Functions For Attribute Handling
- Chapter Summary
- Further Reading
- Desciptor Example: Attribute Validation
- Overriding VS Nonoverriding Descriptors
- Methods Are Descriptors
- Descriptor Usage Tips
- Descriptor docstring and Overriding Deletion
- Chapter Summary
- Further Reading
- A Class Factory
- A Class Decorator for Customizing Descriptors
- What Happens When: Import Time VS Runtime
- Metaclasses 101
- A Metaclass for Customizing Descriptors
- The Metaclass prepare Special Method
- Classes as Objects
- Chapter Summary
- Further Reading
UPDATE:
日期 | 类型 | 详细操作 |
---|---|---|
2017-04-18 | 动笔 | 初始化本文结构 |
2017-04-26 | 重构 | 添加目录和阅读笔记 |