欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

Effective Python 读书笔记

程序员文章站 2022-06-15 10:14:58
不改变列表对象进行列表赋值:a[:] = [1,2,3,...]左边a列表的切片操作能使a对象所指的列表对象不变(id(a)不变)的情况下将a列表的值覆盖为右值翻转列表:b = a[::-1]该方法只对字节串和ASCII字符有效,对UTF-8字节串会报错变量作用域在表达式中引用变量时,python解释器按照如下顺序遍历各作用域,以解释该引用:1)当前函数的作用域2)任何外围的作用域(例如,包含当前函数的其他函数)3)包含当前代码的那个模块的作用域(也叫全局作用域,global sco...

强烈推荐亲自阅读《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