
流畅的Python读书笔记
文章平均质量分 62
lijiachang8
Python、Linux、docker
展开
-
Python 使用future处理并发
从Python3.2引入的concurrent.futures模块,Python2.5以上需要在pypi中安装futures包。future指一种对象,表示异步执行的操作。这个概念的作用很大,是concurrent.futures模块和asyncio包的基础。原创 2023-02-03 23:38:19 · 1812 阅读 · 0 评论 -
Python 协程详解
yield item这行代码会产出一个值,提供给next()的调用方;此外还会做出让步,暂停执行生成器,让调用方继续工作,知道需要使用另一个值再调用next()。调用方会从生成器中拉取值。从语法上来看,协程与生成器类似,都是从定义体中包含yield关键字的函数。可是,在协程中,yield通常出现在表达式的右边(如data = yield),可以产出值,也可以不产出:如果yield关键字后面没有表达式,那么生成器产出None。原创 2023-02-03 23:26:07 · 884 阅读 · 1 评论 -
Python 上下文管理器
with语句会设置一个临时的上下文,交给上下文管理器对象控制,并且负责清理上下问题。这样做能避免错误并减少样板代码,因此API能更安全,更易使用。除了自动关闭文件之外,with块还有很多用途。原创 2023-01-31 23:50:56 · 217 阅读 · 0 评论 -
Python else子句在for、while、try语句中使用
else子句不仅在if语句中使用,还可以用在for、while、try中使用,但是没有得到重视,因为和if/else的差别很大,else这个单词的意思阻碍了对特征的理解。else的含义是“排他性”这层意思:“要么运行这个循环,要么做那件事”,但是在for和while循环中,else的语义正好相反:“运行完这个循环,然后做这件事”所以根据英文含义,使用then关键字更好,在for、while、try语句中也就说得通:比如在try中“尝试运行这个,然后做这件事”示例,else的简单使用。原创 2023-01-31 23:48:20 · 1024 阅读 · 0 评论 -
Python可迭代对象、迭代器和生成器
迭代是数据处理的基石。内存中放不下的数据集,我们要找到一种惰性获取数据的方式,即一次获取一个数据项,这就是迭代器模式在Python2.2加入了yield关键字,这个关键字用于构建生成器(generator),其作用和迭代器一样。所有的生成器都是迭代器。因为生成器完全实现了迭代器接口。迭代器用于从集合中取出元素。生成器用于“凭空”生成元素。比如斐波那契数列中的数有无数个,在集合中放不过下。在Python社区中,大多数时候都把迭代器和生成器视为同一概念。原创 2023-01-31 23:46:05 · 428 阅读 · 0 评论 -
Python 正确重写运算符(重载)
运算符重载的作用是让用户定义的对象使用中缀运算符(如+和|)和一元运算符(如-和~)。在Python中,这些也算是运算符:函数调用:()属性访问:.元素访问和切片:[]原创 2023-01-31 23:37:37 · 2064 阅读 · 1 评论 -
Python继承的优缺点
推出继承的初衷是让新手顺利使用只有专家才能设计出来的框架!原创 2023-01-31 00:04:58 · 385 阅读 · 0 评论 -
Python:从协议到抽象基类
本章话题是接口:鸭子类型代表特征动态协议; 使接口更明确、能验证实现是否副了规定的抽象基类ABC(Abstact Base Class).Python语言诞生15年后,Python2.6中才引入了抽象基类,抽象基类。对于java、C#类似的语言,会觉得鸭子类型的非正式协议很新奇。抽象基类于描述符和元类一样,是用于构建框架的工具。其实很多时候Python开发者编写的抽象基类会对用户施加不必要的限制,做无用功。原创 2023-01-31 00:01:31 · 417 阅读 · 0 评论 -
进阶:Python序列的修改、散列和切片
将以上一篇文章中二维向量Vector2d类为基础(文章链接:进阶:编写符合Python风格的对象_lijiachang8的博客-优快云博客),定义表示多维向量的Vector类。这个类的行为与Python中标准的不可变扁平序列一样。原创 2022-08-19 19:18:25 · 805 阅读 · 0 评论 -
进阶:编写符合Python风格的对象
得益于Python数据模型,自定义类型的行为可以像内置类型那样自然。实现如此自然的行为,靠的不是继承,而是鸭子模型(duck typing)。使用Python的特殊方法,实现一个Pythonic的向量类原创 2022-08-19 19:10:44 · 409 阅读 · 1 评论 -
Python 对象引用、可变性和垃圾回收
简单的赋值不会创建副本。而是增加了别名。对于+=或者*=这种增量赋值来说,如果左边的变量绑定是不可变对象,会创建新对象;如果是可变对象,会就地修改。为现有的变量赋予新值,不会修改之前绑定的变量对象。这叫重新绑定:现在变量绑定了其他对象。如果变量是之前那个对象的最后一个引用,对象会被当做垃圾回收。函数的参数以别名传递。这意味着函数可以修改通过参数传入的可变对象。除非在函数内创建副本,或者使用不可变对象,否则无法避免。使用可变类型作为函数的参数的默认值很危险,如果就地修改了参数,默认值也就变了,这会影响原创 2022-08-19 18:56:14 · 325 阅读 · 0 评论 -
Python 函数装饰器和闭包
函数装饰器和闭包函数装饰器用于在源码中“标记”函数,以某种方式增强函数的行为,用闭包实现。nolocal是在Python3.0新增的保留关键字。闭包除了在装饰器中有用之外,还回调式一步编程和函数式编程风格的基础。装饰器基础,何时执行装饰器装饰器是可调用对象,参数是另一个函数(被装饰的函数)。函数装饰器再导入模块是立即执行,而被装饰的函数只有在调用时运行。装饰器通常在一个模块中定义,然后应用到其他模块中的函数上。registry = []def register原创 2022-04-16 13:31:44 · 845 阅读 · 0 评论 -
Python一等函数实现设计模式
策略模式策略模式是一个经典的模式,简化代码。电商领域有个功能明细可以使用“策略”模式,就是根据客户的属性或订单中的商品计算折扣。比如一个网店,指定了以下的折扣规则, 并且一个订单只能享受一个折扣:有1000积分以上的顾客,整个订单可以享受5%的折扣 同一个订单中,单个商品的数量达到20个以上,单品享受10%折扣 订单中不同商品的数量达到10个以上,整个订单享受7%折扣下面是UML类图:上下文:把一些计算委托给实现不同算法的可互换组建,他们提供服务。 在这个示...原创 2022-04-16 12:39:43 · 614 阅读 · 0 评论 -
Python的一等对象:函数
‘一等对象’定义:在运行时创建 能赋值给变量或者数据结构中的元素能作为参数传递给函数 能作为函数的返回结果在python中,整数,字符串,字典都是一等对象。但是在python中函数也符合以上特征,所有函数都是一等对象。示例,实现阶乘def factorial(num): """阶乘实现 :一个正整数的阶乘是所有小于及等于该数的正整数的积,并且有0的阶乘为1。""" return 1 if num <= 1 else num * factorial(num -原创 2021-12-08 18:43:06 · 833 阅读 · 0 评论 -
Python3的str文本和bytes字节序列 Unicode介绍
python3的str对象中获取的元素是Unicode字符,这相当于从python2中的unicode对象中获取元素,而不是从python2的str对象中获取原始字节序列python3的str类型基本相当于python2的unicode类型。把码位转换成字节序列的过程是编码。 encode (把字符串转换成用于存储或者传输的字节序列)把字节序列转换为码位的过程是解码。 decode (把字节序列变成人类可读的文本字符串)s = 'café'b = s.encode('utf-8')原创 2021-12-08 18:38:42 · 1502 阅读 · 0 评论 -
Python 字典和集合的的实现:散列表
字典和集合的效率高,和他背后的散列表是绕不开的。散列表其实是一个稀疏数组(总是有空白元素的数组称为稀疏数组)。散列表的单元叫做表元bucket。在dict的散列表中,每个键值对都占用一个表元,每个表元都有两个部分,一个是对键的引用,一个是对于值的引用。因为表元的大小一致,所以可以通过偏移量来读取表元。python会保证大概有三分之一的表元是空的,快要达到这个阈值的时候,原有的散列表会被复制到一个更大的空间里面。散列值的相等:内置的hash()方法是调用对象的__hash__。如果两个对象比较原创 2021-10-26 10:45:12 · 447 阅读 · 0 评论 -
Python的集合set简介
11. 集合set和它的不可变类型frozenset直到python2.6版本中才成为内置类型,是比较年轻的。集合的本质是许多唯一对象的聚集。集合的所有元素必须是可散列的。set类型本身是不可散列的,因为可以增删元素。但是不可变集合frozenset是可散列的。所以可以创建一个包含不同frozenset元素的set。集合实现了很多基础的中缀运算符,不仅可以减少代码量,还可以减少python的运行时间:a|b 返回他们的合集 a.union(b, ...) 就地修改 a|=ba...原创 2021-04-22 22:31:00 · 143 阅读 · 0 评论 -
Python中不可变的字典(映射类型)。
不可变映射类型在有些场景中,比如不能用用户错误的修改某个映射,所以需要一种不可变的字典。在Python3.3开始,types模块中新增了一个封装类MappingProxyType。给这个类一个映射,他会返回一个只读的映射视图。虽然这个视图是只读的,但是动态的,意思是如果修改了原映射对象,这个映射视图也能够改变,但是无法直接修改映射视图。from types import MappingProxyTypea_dict = {'x': 1, 'y': 2}a_view..原创 2021-04-22 22:27:38 · 867 阅读 · 0 评论 -
Python继承字典dict,请使用UserDict 作为基类
仅python3可用。UserDict 这个类是把标准的Dict用纯python又实现了一遍。是让用户写子类的。如果想要创建自定义映射类型,以UserDict作为基类,比dict要方便的多UserDict 不是继承自dict。但是UserDict有个data的属性,是dict的实例,是用于存储数据的地方。UserDict是继承自MutableMapping。使用UserDict作为基类,完成一个自定义字典from collections import UserDictc.原创 2021-04-22 22:23:44 · 4015 阅读 · 0 评论 -
Python字典的变种 OrderDict、ChainMap、Counter
在collection模块中,除了defaultdict之外,还有不同的映射类型。OrderDict 有序字典:特殊的popitem方法默认删除字典的最后一个元素,如果是odict.popitem(last=False)调用,会删除并返回第一个添加的元素ChainMap 合并多个字典(映射对象) 仅python3可用:假如你有如下两个字典,在两个字典中执行查找操作(比如先从 a 中找,如果找不到再在 b 中找)。 一个非常简单的解决方案就是使用 collections 模块中的...原创 2021-04-22 22:20:37 · 387 阅读 · 0 评论 -
Python映射类型对象的特殊方法__missing__
所有的映射类型在找不到键的时候,就会调用__missing__方法。如果一个类继承了dict,那么继承类也会提供__missing__方法,在__getitem__时(也就是使用dict[key]取值)找不到键的情况,Python就会自动调用__missing__,而不是抛出KeyError异常。所以,__missing__方法对get和__contains__(in运算符会用到这个方法)这些方法的使用无影响!示例,自定义个映射类型:在查询的时候把非字符串的键,转换为字符串。c...原创 2021-04-19 22:05:32 · 380 阅读 · 0 评论 -
Python处理字典找不到的键defaultdict(默认值字典)
映射方法除了dict,还有常见的OrderDict(有序字典)、defaultdict(默认值字典),他们的方法基本相同,只有个别差异。比如defaultdict 实现了一个d.__missing__(k)方法,当d.__getitem__(k)找不到对应键的时候,就会被调用。__getitem__(k)这个方法,就是d[k],对字典使用中括号的时候调用。创建一个defaultdict,处理找不到的键。collection.defaultdict 是在创建字典对象的时候,需要配置一个找.原创 2021-04-19 21:54:36 · 1828 阅读 · 0 评论 -
Python字典的setdefault()方法来处理找不到的键:统计记录每个单词出现的次数和坐标
字典的setdefault()方法,来处理找不到的键。此方法总会让字典返回key对应的value,如果字典中有对应的key就从字典中取值,如果没有对应的key就会把value设置default,然后再返回。注意,这样字典中已经增加了新的键值对实例:记录每个单词出现的次数和坐标import rewords_count = {}with open('en_words.txt', 'r', encoding='utf-8') as f: for line_num, line .原创 2021-04-19 21:42:34 · 317 阅读 · 0 评论 -
Python的映射类型介绍
dict类型是Python语言的基石,至关重要。Python对它做了高度优化,散列表是字典类型性能出众个跟本原因。collection.abc 模块里面有Mapping和MutableMapping这两个抽象基类,他们的作用为dict和类似的类型提供形式接口。其他的映射类型,一般不会直接继承这两个抽象基类,会直接对dict就行扩展。from collections import abcprint(isinstance({}, abc.Mapping))print(isinstance({},原创 2021-04-19 21:33:52 · 1826 阅读 · 0 评论 -
Python中列表并不是首选,其他序列类型介绍:数组、内存视图、NumPy 、双向队列deque
数组array.array比如我们要存放100万个浮点数的话,使用数组就会更高效一点,因为数组背后存储是不是float对象,而是数字对应的机器翻译,也就是字节表述。数组支持所有可变序列的操作,比如.pop .insert .extend。另外还支持从文件读取和写入更快的方法:.fromfile和.tofile frombytes和tobytes。创建数组,第一个参数需要类型码,用来表示C语音底层如何存放的数据类型,比如arra('b'),B类型码就是signed char 只能存放一个...原创 2021-04-18 17:39:56 · 230 阅读 · 0 评论 -
Python 的bisect模块: 有序序列的查找和插入
查找位置:bisect(array,new_item)import bisecta = [1, 2, 4, 8, 12, 14, 19]item = 13position = bisect.bisect(a, item)print(position) # 如果放到有序序列中,应该存在的索引位置# 使用列表的insert方法插入对应位置a.insert(position, item)print(a)结果:5[1, 2, 4, 8, 12, 13, 14, 19]有序插入原创 2021-04-18 17:23:46 · 484 阅读 · 0 评论 -
Python的list.sort方法 和 sorted函数
不同点:list.sort方法是就地排序,不会把源列表复制一份,返回值是None。python中就地改动都会返回None。sorted函数,新建一个列表作为返回值,参数可以是不可变序列,或者是生成器,最后总会返回一个列表。共同点:reverse ,默认为FALSE,改为True会降序,从大到小。 key,排序算法...原创 2021-04-18 17:19:30 · 155 阅读 · 0 评论 -
Python序列的增量赋值+= *=
增量赋值运算符 +=和*= 一般作用于可变序列上如果对于不可变序列(如tuple), 每次都会生成一个新的对象,效率就很低。+= 对应的方法__iadd__就地加法。如果一个类没有实现,python会退一步调用__add__a +=b以上实例中,如果a实现了__iadd__方法,对于可变序列(list、bytearray、array.array)来说,a会就地改动,等于调用了a.extend(b)。如果没有实现__iadd__就是等于a = a+b 先计算a+b等到一个新的对象..原创 2021-04-17 15:45:47 · 350 阅读 · 0 评论 -
Python切片 slice() 对切片赋值、嫁接、修改
seq[start:stop:step] 通常最后一个step是省略的默认为0。在start和stop之间以step为间隔取值python会调用seq.__getitme__(slice(start,stop,step))s = 'bicycle'切片s[::3] 结果:bye 这里注意是间隔,所以要从索引0的b开始,依次往后三个数切片s[::-2] 结果:eccb step负数倒着数,不要忘记从索引0开始slice()方法对序列类型使用sl...原创 2021-04-17 15:43:10 · 470 阅读 · 0 评论 -
Python元组作为记录,元组拆包,命名元组namedtuple
元祖作为记录元祖其实是对数据的记录,元祖的每个元素存放了记录中字段的一个数据,外加这个字段的位置。也就是位置是有含义的lax_coordinates = (33.94, -118.40) # 一个经纬度city, year = ('Tokyo', 2003) # 赋值 拆包traveler = ('USA', '311') # 地区信息print('%s/%s' % traveler) # %的匹配print('{}/{}'.format(*traveler)) # 拆包.原创 2021-04-17 15:19:56 · 275 阅读 · 0 评论 -
Python对象的表示形式 __str__和__repr__
获取对象的字符串表示形式的标准方式,Python提供了两种。repr() :返回便于开发者理解的方式返回对象的字符串,用__repr__实现 str():返回便于用户理解的方式返回对象的字符串,用__str__实现其他的表示形式,还有:__bytes__:类似于__str__方法,bytes()函数调用它获取对象的字节序列表示形式。 __format__:会被内置的format()函数和str.format()方法调用,适应特殊的格式代码显示对象字符串表示形式。ps:在Python3中.原创 2021-04-16 21:55:10 · 146 阅读 · 0 评论 -
Python的弱引用、控制台的_变量、WeakValueDictionary的介绍
弱引用因为有引用,对象才能在内存中存在。当对象的引用数量归零后,垃圾回收程序会把对象销毁。但是有时候需要引用对象,但是不想影响对象的生命周期,这经常用在缓存中。弱引用不会增加对象的引用数量。引用的目标对象称为所指对象(referent)。因此弱引用不会妨碍所指对象被当做垃圾回收。弱引用在缓存应用中很有用,因为我们不想因为缓存占用着对象,而不被回收。使用weakref.ref获取所指对象的弱引用。如果对象存在,调用弱引用可以返回对象,否则返回None。示例,使用weakre..原创 2021-04-16 21:52:52 · 871 阅读 · 1 评论 -
Python的del和垃圾回收
对象绝不会自行销毁;然而,无法得到对象时,可能会被当做垃圾回收。del语句是删除名称,而不是对象。del语句可能会导致对象被当做垃圾回收,但是仅当删除了变量保存的是对象的最后一个引用,或者是无法得到对象的时候(比如两个对象相互引用)。还有就是重新绑定也可能导致对象的引用数量归零,导致对象被销毁。在即将销毁实例时,Python解释器会调用__del__方法,给实例最后的机会,让其释放外部资源。自己编写的代码很少需要用到__del__代码,因为__del__很难用,费力不讨好。在CPyth.原创 2021-04-16 21:48:38 · 629 阅读 · 0 评论 -
Python列表推倒的知识点:变量泄露、列表推导代替filter和map函数、生成笛卡尔积、生成器表达式
列表推导的变量泄露问题在python2.x中,列表推导中的关键字可能会影响上下文的同名变量:在python3中不会有问题,推导式,生成式,在python3中有了自己的局部作用域,就像函数一样。列表推导代替filter和map函数filter和map组合,不一定比列表推导式快,而且列表推导的可读性会更好一些。列表推导实现:symbols = 'asdfgjk'ascii = [ord(x) for x in symbols if ord(x) > 127...原创 2021-04-15 22:26:03 · 326 阅读 · 0 评论 -
Python内置类型,序列类型介绍
模拟数值类型自定义bool值判断一个实例是否为真,会调用x.__bool__()的结果,如果没有__bool__方法,会继续调用__len__方法,如果返回0 就是FALSElen()不是一个普通方法如果x是一个内置类型的实例,len(x)速度会非常快,因为CPython会调用C结构体读取对象的长度,不会调用其他方法内置序列类型容器序列:list、tuple、collecttions.deque(双向队列) 这些序列可以存放不同的类型容器序列中存放的是对象的引用...原创 2021-04-15 22:19:43 · 268 阅读 · 0 评论 -
Python完成一个纸牌类,pythonic的纸牌
import collectionsCard = collections.namedtuple('Card', ['rank', 'suit'])# suit 花色# rank 牌面大小class FrenchDeck: ranks = [str(x) for x in range(2, 11)] + list('JQKA') suits = 'spades diamonds clubs hearts'.split() def __init__(self): .原创 2021-04-15 22:17:34 · 213 阅读 · 0 评论 -
Python中函数的传参是引用的传递
函数的传参是引用Python唯一支持的参数传递模式的共享传参(call by sharing)。多数面向对象语言都采用这个模式。共享传参是指函数中各个形式参数获得的是实参的引用的副本。也就是说,函数内部的形参是实参的别名。这样的结果就是,函数可能会修改作为参数传入的可变对象,但不会改变标识。千万不用使用可变类型作为参数的默认值!一个简单的Bus类,使用可变类型作为参数,结果变成了幽灵列车了。。。示例class Bus: def __init__(self, pas.原创 2021-04-15 22:13:12 · 327 阅读 · 0 评论 -
Python理解 浅拷贝和深拷贝deepcopy
Python默认是浅拷贝,比如使用拷贝一个列表l1 使用l2=list(l1) 或者l2=l1[:] 都是浅拷贝。 (l2=l1这不是拷贝,这是别名,多了一个引用)浅拷贝:只复制了最外层的容器,副本中的元素是源容器中元素的引用。如果所有元素都是不可变的,那么这样没问题,还能节省内存。但是浅拷贝中有可变的元素,会导致很多想不到的问题。l1 = [3, [66, 55, 44], (7, 8, 9)]l2 = list(l1) # 浅拷贝,此时l1 is l2 = FALSEl1.app..原创 2021-04-15 22:11:14 · 351 阅读 · 0 评论 -
Python变量的引用、标识、相等性 is和==区别
变量不是盒子变量是标注,而不是盒子。Python变量类似于Java中的引用式变量,因为最好理解为附加在对象上的标注。对于引用式变量来说,说把变量分配给对象更加合理。把变量s分配给'xxx',而不是说把'xxx'分配给s。示例,创建对象之后才会把变量分配给对象>>> class Giz:... def __init__(self):... print('Giz id is{}'.format(id(self)))...&...原创 2021-04-15 22:08:29 · 367 阅读 · 0 评论 -
Python 参数化装饰器 1.实现注册注销功能 2.可配置打印格式的函数计时器
想要实现装饰器接收参数,需要创建一个装饰器工厂函数,把参数传给他,返回一个装饰器,然后再把它用在要装饰去函数上。一个参数化的装饰器,让register装饰器具备可选注册和注销功能。通过设置一个参数,设为FALSE时,不注册被装饰去函数。注意此时register函数不是装饰器,而是装饰器工厂函数。调用它时才会返回真正的装饰器。示例,接收参数的注册功能装饰器registry = set() # 使用集合,添加和删除速度更快def register(active=True):..原创 2021-04-14 22:26:24 · 173 阅读 · 0 评论