《Advanced Guide to Python3 Programming(Second_Edition)》笔记
Python Type Hints
Type Hint is additional type information that can be used with a function definition to indicate what types parameters should be and what type is returned.
This is illustrated below:
1 | def add(x: int, y: int) -> int: |
But it is still possible to pass a string into the add() function as far as Python is concerned.
However, static analysis tools (such as MyPy) can be applied to the code to check for such misuse.
Class Slots
问题:python可以在运行时动态定义类成员,导致无法提前预知和管理类成员
解决方案:使用slots
1 | class Person: |
这样,在动态定义slots之外的类成员时,将会在运行时报异常AttributeError
slots会减小类实例大小,有利于提升性能
Weak References
弱引用相关接口:
- weakref.ref(object[, callback])—This returns a weak reference to the object.
- weakref.proxy(object[, callback])—This returns a proxy to object which uses a weak reference.
- weakref.getweakrefcount(object)—Return the number of weak references and proxies which refer to object.
- weakref.getweakrefs(object)—Return a list of all weak reference and proxy objects which refer to object.
1、将对象的所有强引用被释放时,弱引用自动失效
2、weakref.proxy 获取的弱引用对象是原对象的代理,可直接像原对象一样调用各成员;weakref.ref 获取的弱引用对象,需要额外解一层,其它一致
1 | class Data: |
Data Classes
数据类是为了方便快捷定义实体类的语法糖1
2
3
4
5
6
7
8from dataclasses import dataclass
@dataclass
class Trade:
"""Class for representing Equity Trades"""
counter_party1: str
counter_party2: str
symbol: str
amount: int = 0
这种便捷也带来了几个问题:
1、初始化问题:可变类型成员的初始化,不能使用普通的语法,需要使用工厂方法,否则会导致所有实例的该成员变量,实际指向一个对象。(因为成员是在类加载的时候初始化的,而默认的init没有对成员变量再次显式初始化)
1 | from dataclasses import dataclass, field |
2、继承链中参数默认值问题:如果父类使用的默认值来初始化成员,会导致子类的所有成员变量都要提供默认值。(因为没有显式的init,子类的默认init要想正确初始化所有成员,就要满足所有有默认值的参数就放在参数列表的后面)
3、为了对数据类增加日志监控,同时避免增加方法成员破坏数据类的简洁,额外引入post_init成员,该成员在init之后执行
杂项
类的str 与 repr的区别
在 Python 中,str 和 repr 都用于返回对象的字符串表示,但它们的用途和设计目标不同。以下是主要区别:
- 目标用户不同
str:面向用户,提供更友好、可读性强的字符串表示。
repr:面向开发者,提供明确、无歧义的字符串表示,通常用于调试或日志。
- 调用场景不同
str 会在以下情况被调用:
使用 print(obj) 或 str(obj) 时。
在格式化字符串(如 f"{obj}")中。
repr 会在以下情况被调用:
直接在交互式环境(如 Python Shell)中输入对象名并按回车时。
使用 repr(obj) 时。
当 __str__ 未定义时,会回退到 __repr__。
- 返回值要求不同
str:返回的字符串可以是简化的、更人性化的形式。
repr:返回的字符串应尽量明确,理想情况下应是一个合法的 Python 表达式,能通过 eval(repr(obj)) 重新生成原对象。
- 默认行为不同
如果未定义 str,Python 会默认调用 repr。
如果未定义 repr,Python 会使用基类(如 object)的默认实现(通常返回
1 | class Person: |