Effective Python 读书笔记
强烈推荐亲自阅读《Effective Python》([美]Brett Slatkin著)
对Python学习有莫大的帮助
不改变列表对象进行列表赋值:
a[:] = [1,2,3,...]
左边a列表的切片操作能使a对象所指的列表对象不变(id(a)不变)的情况下将a列表的值覆盖为右值
翻转列表:
b = a[::-1]
该方法只对字节串和ASCII字符有效,对UTF-8字节串会报错
变量作用域
在表达式中引用变量时,python解释器按照如下顺序遍历各作用域,以解释该引用:
1)当前函数的作用域
2)任何外围的作用域(例如,包含当前函数的其他函数)
3)包含当前代码的那个模块的作用域(也叫全局作用域,global scope)
4)内置作用域(也就是包含len和str等函数的那个作用域)
迭代容器
迭代容器和可迭代对象不同,前者可将__iter__方法实现为生成器, 则每次迭代的时候都能获得一个新的可迭代对象(iter(object)可返回新的迭代对象)。可迭代对象则会返回自身(iter(object) is object)
super方法
super方法调用顺序,可以通过CClass.mro()方法得到,顺序是会从基类开始往上依次调用。(CClass为某个子类的类名)
私有属性
Python会对私有属性的名称做一些简单变换,如
class MyChildObject(MyParentObject)
def get_private(self)
return self.__private
class MyParentObject()
def __init__(self):
self.__private = 0
其中就会将父类的私有属性改名为_MyParentObject__private,所以我们在子类中也可以直接通过MyChildObject._MyParnteObejct__private来访问该私有变量
魔术方法
Python中使用下标访问元素时,会将代码转译为__getitem__(index),所以我们可以为自定义的容器类实现__getitem__(self, index)方法,实现下标访问元素
实现len()操作的话需要实现__len__方法
继承内置collections.abc中的抽象基类可以提示你需要实现什么方法,只要实现了所需的方法,其余一些该容器应有的方法就会自动实现。
__set__(self, instance, value)和__get__(self, instance, instance_type),__delete__(self, instance)为描述符协议方法,实现了任一方法的类可作为一个具有绑定行为的对象属性,当访问、赋值删除改属性时就会调用对应的方法。
__getattr__(self, name)方法:
如果某个类定义了__getattr__,同时系统在该类的对象实例字典中找不到带查询的属性,则会调用这个方法
__getattribute__(self, name):
每次访问对象的属性时都会调用这个方法,即便属性字典里已经有了该属性
__setattr__(self, name, value):
无论是直接赋值还是调用内置的setattr函数赋值都会触发__setattr__方法
由于__setattr__和__getattribute__在每次赋值或访问属性时都会触发,因此如果要在这两个方法中访问或赋值属性,可以通过super().__getattribute__和super().__setattr__的方式。
属性装饰器
@property装饰器会将一个类方法装饰成属性
如:
@property
def hsv(self):
return self._hsv
在调用self.hsv时,则会调用该方法,获得self._hsv的值
而用其setter装饰器装饰方法后,在给该属性赋值的行为都会变为调用该方法
@hsv.setter
def hsv(self, para):
do_anything
self._hsv = para
元类
定义元类要继承type,对于其他使用该元类的其他类而言,Python默认会把那些类的class语句体中所含的相关内容发送给元类的__new__方法
class Meta(type):
def __new__(meta, name, bases, class_dict):
...
class MyClassInPython2(object):
__metaclass__ = Meta
我们可以在元类的new方法中验证子类的参数是否被有效构建(元类的__new__方法在定义子类的语句执行时就会被执行)
借用该元类的功能,我们可以做到在类被定义的同时将类注册到我们想要的地方,甚至可以在类定义同时注解描述符属性对象
GIL
全局解释器锁,该机制导致python程序无法同一时刻只能有一个线程向前运行,无法真正做到并行。但是仍然会有数据不安全的问题
协程(coroutine)
工作原理:每当生成器函数执行到yield表达式的时候,消耗生成器的那段代码,就通过send方法给生成器回传一个值,而生成器收到这个经send方法传进来的值之后,会将其视为yield表达式的执行结果
def minimize():
current = yield
while True:
value = yield current
current = min(value, current)
it = minimize()
next(it) # 为了让代码运行到current = yield处
print(it.send(10))
print(it.send(4))
print(it.send(22))
>>>
10
4
4
第一个yield语句中的yield关键字后没有跟随其他内容,这条语句意思是将外界传进来的某个值当成当前的最小值。而while中的yield语句会将current输出,并将外界传入的下一个值作为表达式结果
本文地址:https://blog.csdn.net/noob404/article/details/107655726