好玩好用的Python
文章平均质量分 91
南宫理的日知录
左手人文,双手科技
展开
-
71、Python之函数式编程:不能定义常量,Python如何支持不可变性?
本文从软件架构作为切入点,将程序代码的可读性、易于调试、测试的建议,和编程范式的各种减法型规范,联系在一起,从而对设计原则、软件架构及编程范式有了更深入的理解。最后,通过Python关于不可变性的支持,探讨了关于程序状态和结果的确定性的本质。原创 2024-09-18 06:15:00 · 509 阅读 · 0 评论 -
70、Python之函数式编程:一文搞懂函数式编程的核心概念
本文首先简单介绍了编程范式的概念,然后梳理了编程语言与编程范式的关系。在此基础上,引入了函数式编程这一范式,着重介绍了为什么要学习函数式编程。最后,系统梳理了函数式编程的核心概念,从而对后续学习函数式编程有一个纲领性的了解。原创 2024-09-14 07:26:38 · 1227 阅读 · 0 评论 -
69、Python番外篇:从编程范式看如何学习一门编程语言的精髓
所谓“范式”,可以简单理解为“示范”、“样板”等,也可以理解为对一些相对固定的问题域所总结、形成的最佳实践所需要遵从的基本原则、模式等。所谓“编程范式(Programming Paradigms)”是在组织和构建程序中所应用的思维模式、方法论或者是一套需要遵循的实践原则。理解和掌握编程范式有助于程序员快速选择最合适的方法来进行编程,以解决特定的问题。需要说明的是,由于具体的业务场景、问题域的不同,对应就存在多种不同的编程范式。如同我们选择编程语言时,语言之间没有绝对的高下之分。原创 2024-09-13 08:37:49 · 893 阅读 · 0 评论 -
68、Python之函数高级:一文搞懂dataclass,快速定义数据类
dataclass的特性是在Python3.7之后开始引入的,如果自己的Python环境是相对较老的版本需要注意一下。在开始使用dataclass之前,我们先来看下dataclass的定义:从定义中,我们应该有如下认知:1、dataclass是一个函数装饰器,这个函数装饰器用于对类进行装饰增强。2、这个装饰器的实现是基于类中定义的字段,自动生成相应的方法。原创 2024-09-13 05:30:00 · 1323 阅读 · 0 评论 -
67、Python之函数高级:通过内部装饰器实现LRU缓存、函数重载
在我们介绍Python中面向对象的内容中,其实我们已经使用了Python的几个内部装饰器。在当时,我们把这些只是简单地当做特定的语法规范,就得这么着的感觉。通过对装饰器内容的介绍,我们应该对他们有了更深入的理解。接下来,就简单回顾一下这些装饰器。由于我们已经比较自然地使用这些内部装饰器了,我们接下来只是回顾,并看下这些内部装饰器的定义,不再演示装饰器的使用。这个装饰器用于在类中定义一个静态方法。静态方法的使用不需要访问实例对象或者类对象,因此,不需要self或者cls参数。原创 2024-09-12 06:00:00 · 873 阅读 · 0 评论 -
66、Python之函数高级:一个装饰器不够用,可以多装饰器buffer叠加
本文以对“大而全”和“小而美”的设计的疑问为出发点,引出了对单一职责原则的理解与实践,并通过遵循SRP的装饰器设计,实现了多个装饰器对原始函数的buffer效果的叠加,看到更加灵活的组合使用。原创 2024-09-11 07:30:52 · 1158 阅读 · 0 评论 -
65、Python之函数高级:装饰器实战,通用日志记录功能的动态添加
本文简单介绍了日志的主要组成部分,以及日志记录的重要性。简单介绍了Python中利用logging模块进行日志记录的简单使用案例。最后,编写一个可以自行控制日志记录开关的类装饰器,来实现日志记录功能的动态扩充。原创 2024-09-10 11:18:30 · 1111 阅读 · 0 评论 -
64、Python之函数高级:装饰器实战,动态语言也能有类型检查
本文分别介绍了Python中类型注解的特性、函数签名的概念,以及通过inspect获取函数签名信息、通过bind()、bind_partial()实现对函数签名进行参数的绑定。最终通过一个完整的类型检查的实现代码,展示了通过装饰器实现动态语言的动态类型检查的实现。原创 2024-09-09 08:01:15 · 1038 阅读 · 0 评论 -
63、Python之函数高级:装饰器缓存实战,优化递归函数的性能
本文简单介绍了递归函数的概念以及递归函数的特性,然后看到了递归函数最大的问题是大量重复计算导致的性能较差的问题。最后,我们通过两个方法实现了对递归函数的性能的优化,优化的核心在于以空间换时间,规避大量的重复计算。原创 2024-09-07 14:57:56 · 916 阅读 · 0 评论 -
62、Python之函数高级:装饰器导致函数元数据丢失?三种方法搞定
本文简单回顾了函数对象中主要的元数据(本质上就是对象中的属性),然后正视了装饰器的引入所导致的函数对象元数据丢失同步的问题。最后,通过3个方法实现了装饰器内部函数与原始函数的元数据同步的需求。原创 2024-09-06 07:37:57 · 922 阅读 · 0 评论 -
61、Python之函数高级:为函数添加方法,实现属性可变的装饰器
其实,这一点比较简单,只需要把函数当作Python中的一个普通对象即可。但是,如果一直执着于函数本身,则理解起来,会有些拧巴。base = 0print('执行加法运算')print(f'变更后:add.base={x}')执行结果:首先要说明的,这是一个很拧巴的把函数当作普通对象进行使用的演示代码。可以看到,我们给函数对象添加了一个change_base()的方法,用于修改add函数对象的base属性(当然,如果不存在base属性,就会动态添加一个base属性)。原创 2024-09-05 06:00:00 · 1156 阅读 · 0 评论 -
60、Python之函数高级:从函数对象的理解,学习类装饰器的使用
1、如果一个类中实现了__call__()方法,则对该类的实例对象进行:对象名()的操作时,Python解释器会自行查找__call()方法,并执行。2、结合函数对象,以及普通对象,我们可以得到一个更加完备的结论:当Python解释器遇到:对象名()的表达式时,首先会判断该对象是否是函数对象(或者方法对象),如果是,则会直接执行其函数体中的代码(__code__中);如果不是,则会查找对象中是否具有__call__()方法,有则执行;否则,抛出异常。原创 2024-09-04 15:07:12 · 1164 阅读 · 0 评论 -
59、Python之函数高级:带参数的装饰器实现更加灵活的增强效果
本文首先简单回顾了装饰器的相关知识点,更加理解了装饰器本质上是一个高阶函数的概念。然后,通过一个不太恰当的案例,引出带参数的装饰器的需求。最后,通过带参数的装饰器以及一种变通的写法,实现案例的需求。原创 2024-09-04 09:03:08 · 823 阅读 · 0 评论 -
56、Python之函数高级:学了不会用?高阶函数在功能迭代中的实践
本文以部分技术特性似乎没有什么作用为出发点,思考了关于技术如何学习的三个重点,以及基于高阶函数,探讨了功能迭代时,如何很好地应对。原创 2024-09-02 06:30:00 · 984 阅读 · 0 评论 -
57、Python之函数高级:装饰器,开闭原则下增强函数功能
本文首先回归了开闭原则的相关内容,然后介绍了开闭原则的一个最佳实践——装饰器模式,最后简单介绍了Python中装饰器的用法。需要说明的是,本文只是简单介绍了一下装饰器,装饰器中还有一些稍微复杂的内容,我们在后面的文章再一一介绍。原创 2024-09-02 12:00:00 · 871 阅读 · 0 评论 -
58、Python之函数高级:不定参数的函数,写出更加通用的装饰器
本文首先说明了之前比较粗糙的装饰器实现的缺陷,由于参数形式、返回值等的写法大大降低了装饰器的通用性的问题;然后,回顾了接收任意参数的函数的定义;最后,基于接收任意参数的函数的写法最终优化了装饰器的实现,从而让装饰器变得更加通用。原创 2024-09-03 15:04:22 · 952 阅读 · 0 评论 -
55、Python之函数高级:一篇文章彻底搞懂什么是“闭包”
本文详细解释了闭包的定义、本质,以及函数、闭包、对象这几个概念的区别与联系,同时介绍了闭包成立的条件以及相关内部状态的存储机制。在理解了闭包的基础之上,再次回顾了LEGB规则。原创 2024-08-30 06:15:00 · 1286 阅读 · 0 评论 -
54、Python之函数高级:函数深度剖析,一次性搞懂函数对象
本文重点介绍了函数对象中的比较重要的属性,以及通过函数类进行函数对象的实例化,然后展开介绍了函数属性中的__code__属性中的相关属性,从而对Python中的函数对象有了更深入的理解。原创 2024-08-29 06:45:00 · 1370 阅读 · 0 评论 -
53、Python之函数高级:一等公民中的高阶函数,高在哪里?
在编程语言的语境中,所谓的“高阶函数(Higher-Order Function)”,是指在编程中至少满足以下两个条件之一的函数:1、接受一个或者多个函数作为参数:高阶函数的内部可以调用传入的函数,从而实现更高级别的抽象和代码服复用。2、返回一个函数:高阶函数可以生成新的函数,从而实现动态行为和延迟计算的特性。从以上的描述可以看出,虽然函数作为一等公民符合四个特权。但是,特权可以用,也可以不用。如果用了函数作为参数,或者函数作为返回值的特权,那么该函数才是高阶函数。原创 2024-08-28 06:45:00 · 1871 阅读 · 0 评论 -
52、Python之函数高级:作为一等公民的函数对象
Python中“一切皆对象”的设计理念,使得函数作为一等公民的存在显得更加自然。在高阶函数处理及函数式编程的场景中,Python相对Java或者C语言等,会显得更加合适一些。原创 2024-08-27 13:49:34 · 918 阅读 · 0 评论 -
51、Python之模块和包:Python的包和文件夹有何区别
本文简单介绍了Python中的两种包:命名空间包和传统包,展开论述了关于责任转嫁的问题,最后介绍了__init__.py文件在命名空间包存在的情况下,仍然能发挥的作用。原创 2024-08-27 08:34:58 · 875 阅读 · 0 评论 -
50、Python之模块和包:入口文件和模块,Python项目组织的最佳实践
本文介绍了模块中的几个关键内置变量,介绍了模块和入口文件的区别,以及入口文件的作用,最后给出了一些Python项目代码组织的最佳实践。原创 2024-08-26 15:15:01 · 762 阅读 · 0 评论 -
49、Python之模块和包:模块导入对命名空间的影响
本文首先介绍了命名空间相关的补充内容,然后演示了模块导入对命名空间的影响。需要注意的有这几点:1、当在顶级代码块或者全局作用域中,globals()和locals()获取的命名空间字典都是相同的,都是该模块的全局命名空间。2、在函数体内或者局部作用域中,globals()是全局命名空间,locals()则是真正的局部命名空间,只有函数的形参及函数体内定义的变量。原创 2024-08-26 05:30:00 · 1210 阅读 · 0 评论 -
48、Python之模块和包:当导入模块时,Python解释器做了什么
为了更好地理解Python中模块导入的过程及细节,本文首先回顾了Python中的数据模型,然后引入了执行模型的概念。之后,简单介绍了Python中的命名空间,4种命名空间的含义及其生命周期。基于执行模型及命名空间的概念,对Python中的模块导入全过程做了一个系统性的梳理。在下一篇文章中,将通过实际的代码执行,验证一下Python模块导入、加载的过程。原创 2024-08-23 06:45:00 · 1155 阅读 · 0 评论 -
47、Python之模块和包:一次性搞懂import的模块导入
本文首先列举了常用的模块导入的方式,其次,讲解了关于模块导入的前置条件——模块的查找路径,以及sys.path的读取与动态更新。最后,简单介绍了一下相对定位与绝对定位的概念,建议尽量使用绝对定位,从而降低冲突的风险并提高代码的可读性。原创 2024-08-22 06:30:00 · 2057 阅读 · 0 评论 -
46、Python之模块和包:一切皆对象,模块和包也不例外
本文简单介绍了模块化思想的由来,及其在更高级别的代码复用场景中的应用。在Python中模块和包,对应与Python文件及文件夹,而且,模块和包都是对象,是module类的实例化对象。本文只是简单引入了模块和包的概念,具体的使用细节,在后面的文章中将一一补充说明。原创 2024-08-21 06:30:00 · 1168 阅读 · 0 评论 -
45、Python之面向对象:综合应用,基于GUI实现会动的游戏英雄
本文通过一个GUI程序的开发,来展示面向对象设计、开发理念的真实应用场景,帮大家消除面向对象似乎只停留在理论上的误解,基于面向对象能开发出更多好玩、有用的程序。后续有机会,会专门就基于PySide6的GUI程序开发、使用Python进行小游戏的开发进行展开介绍。原创 2024-08-20 13:40:36 · 765 阅读 · 0 评论 -
44、Python之面向对象:孔乙己,实现单例模式,我有4种方法
三大特性、四种数据封装、三种方法、三种类。代码复用(如何更好地偷懒)。其次,通过介绍单例模式的实现方法,对面向对象的实例化对象构建及元类的核心内容进行了复习,并对后续要介绍的装饰器、模块的内容做了一个引入。原创 2024-08-20 07:04:20 · 1092 阅读 · 0 评论 -
43、Python之面向对象:元类繁琐且吃力,不妨尝试__init_subclass__
_init_subclass__()方法是在Python 3.6中引入的一个特殊方法,这个方法在基类中进行定义,当创建该基类的子类时会自动调用。该方法的主要用途是在父类中定义一些特殊逻辑,当子类被创建时,这些逻辑会自动执行。这样使得父类可以对子类进行一些初始化或者配置操作,而不需要子类显式地定义某个方法实现相同的逻辑。如同元类的使用场景一样,通过__init_subclass__()方法,我们也能实现注册表、子类定义检查、子类的动态增强等功能。原创 2024-08-19 11:45:00 · 1131 阅读 · 0 评论 -
42、Python之面向对象:元类应用于定义检查、动态注入、插件注册
由于元类能够控制类对象的创建,所以,如果需要对类的定义进行检查、校验,比如必须写方法的文档注释,必须实现特定方法等,则可以在元类中来实现这些逻辑。比如,假如有这样一个场景,要用到我们的框架的,在用户自定义类时,必须基于框架提供的元类进行类的定义,同时方法的定义中必须添加文档描述。continuecontinueraise TypeError(f"方法{key}必须添加docstring描述")""" 这是方法描述 """print(f"save()方法,可以是保存到数据库的逻辑")原创 2024-08-19 05:30:00 · 896 阅读 · 0 评论 -
41、Python之面向对象:一切皆对象,元类与类对象的创建
本文仍然以“一切皆对象”的概念为出发点及主轴,进行了相关面向对象的知识的补充说明。首先简单介绍了“元”的概念,并通过类比的方式引出来“元类”的概念。其次,回顾了type的定义,并通过代码实例展示了type的两种用法。最后,通过代码的演示,说明了type是一切元类的类,是定义类的默认元类的概念。需要说明的是,今天的内容更偏向于底层原理的介绍,感兴趣的可以自行进行进一步的深入研究。关于元类的具体使用场景,将在下一篇文章中进行介绍。原创 2024-08-16 06:15:00 · 791 阅读 · 0 评论 -
40、Python之面向对象:扩展的对象属性解析顺序(描述符 + MRO)
本文介绍了属性描述符的种类,并比较了不同的属性描述符在属性解析时的差异,最后结合属性描述符、__getattribute__()、__getattr__()及MRO等,给出了一个相对完整的属性解析顺序。需要说明的是,属性描述符及后面的文章中要介绍的元类的概念,在通常意义的业务场景中是很少用到的。但是,如果涉及到框架的开发或者需要阅读框架的源码时,对这些内容的掌握还是很有必要的。原创 2024-08-15 06:30:00 · 713 阅读 · 0 评论 -
39、Python之面向对象:对象属性解析:MRO不够用,补充3个方法
关于实例对象的属性解析,本文回顾了继承中的属性解析属性,并且补充了可以影响属性解析行为的3个函数/方法。当我们把属性描述符引入时,属性的解析顺序将会更加复杂,关于这部分内容,我们在下一篇文章中继续展开。原创 2024-08-14 06:45:00 · 970 阅读 · 0 评论 -
38、Python之面向对象:再聊一下property,及泛化后的属性描述符
本文完整地介绍了property的用法及其对应的get、set、delete的三种操作的方法的封装。并介绍了相较于property更加通用的属性封装的方法——属性描述符。需要说明的是:1、property是描述符的一种特殊形式。2、描述符提供了更大的灵活性和访问控制力,但是property提供的接口一般来说更加直观易读,且更加简洁。3、在使用中,如果只有少量简单的属性需要加访问控制,可以选择使用property来实现,从而更加直观易读;但是,如果涉及到多个属性需要进行访问控制,则可以考虑使用描述符。原创 2024-08-13 06:45:00 · 1044 阅读 · 0 评论 -
37、Python之面向对象:通过property兼顾属性的动态保护与兼容性
本文从一个有缺陷的设计的实际场景出发,引出了两种设计的优化方法,通过比较发现,使用property的方式能够实现一种兼容性更好的代码重构优化的方法。其实,除了进行兼容性更好的代码重构,通过property还可以实现只读属性的设计(只定义@property,不定义xxx.setter)、延迟计算/动态计算的属性(比如只定义半径属性,通过property定义面积、周长的动态计算的属性)等。感兴趣的同学可以自行尝试。原创 2024-08-12 12:43:05 · 1186 阅读 · 0 评论 -
36、Python之面向对象:容器类协议与collections.abc
本文梳理了collections.abc模块中的容器抽象类继承关系,展示了继承关系图。并对其中的比较关键的抽象基类所承载的容器类协议作了逐一说明。然后简单验证了内置容器类list与MutableSequence之间的关系。原创 2024-08-12 08:25:31 · 1030 阅读 · 0 评论 -
35、Python之面向对象:基于抽象类半成品,高效实现自定义序列类
这篇文章中,我们通过两种方式,实现了自定义序列类的效果,使得自定义类的实例对象也支持内置对象的类似的行为。需要说明的是,这些__xxx__的方法,在Python中被称为“魔术方法”,可以理解为要想对象支持某种行为,需要遵守的协议。感兴趣的同学,可以试一下,即使不显式继承任何类,只需要在类中实现特定的魔术方法,也能实现[]索引、for循环遍历等效果。关于魔术方法的内容,在后续的文章中,将会进行系统的介绍。原创 2024-08-10 07:15:00 · 763 阅读 · 0 评论 -
34、Python之面向对象:定义类不让实例化?不讲还是很讲武德
首先来了解一下什么是abc。引言中已经简单提到了,所谓abc,是抽象基类的概念,在Python中有一个对应的用于定义抽象基类的模块abc。抽象基类是一种用于定义接口的方式,允许开发者在类的层次结构中,强制实现特定方法。主要用于定义接口,并确保字类实现这些接口方法。首先看一下abc模块的定义,abc.py这个模块中只有189行代码,暂时我们要用到的有两个:ABC类和abstractmethod装饰器,这里把它们的定义放出来:通过继承ABC类,我们可以定义一个抽象基类。原创 2024-08-09 07:30:00 · 750 阅读 · 0 评论 -
33、Python之面向对象:实例对象太占内存,可以试着这样做
1、定义__slots__属性后,会将该类的实例对象的数据将不再使用默认的基于字典的方式存储,而采用基于数组的更加紧凑的方式进行存储,内存的占用和执行时间将得到大大消减。2、一但使用了__slots__属性,将会失去一些动态语言的灵活性,比如不能动态添加新的属性了,所以,具体使用时,需要进行权衡取舍。3、当在继承中使用__slots__时,需要尤其注意。如果继承自使用__slots__的基类,那么子类也需要定义__slots__来存储自己的属性(即使它不会添加任何属性,也应该如此)。原创 2024-08-08 07:15:00 · 1085 阅读 · 0 评论 -
32、Python之面向对象:对象的表示,再论Python是dict包括语法糖
1、对象底层是对dict做了一层弱封装,不管是实例对象还是类对象。2、类中定义的类属性属于类,存储在类对象的__dict__属性对应的字典中;类的__init__初始化方法或者实例对象中动态添加的属性,属于实例对象,存储在实例对象的__dict__属性对应的字典中。3、类中定义的方法,不管是实例方法、类方法,还是静态方法,都属于类,统一存储在类对象的__dict__属性对应的字典中。4、实例方法其实就是普通的函数对象,类方法和静态方法分别对函数对象做了一层对应的封装。原创 2024-08-07 07:00:00 · 804 阅读 · 0 评论