Python实践提升
文章平均质量分 88
需要掌握基本的Python知识
andyyah晓波
这个作者很懒,什么都没留下…
展开
-
Python实践提升-结语
虽然本专栏自始至终都在说“如何把 Python 代码写得更好”这件事,但我还是希望最后提醒你一句:不要掉进完美主义的陷阱。因为写代码不是什么纯粹的艺术创作,完美的代码是不存在的。有时,代码只要能满足当前需求,又为未来扩展留了空间就足够了。我深知写代码这件事很难,而给大型项目写代码更是难上加难。写好代码没有捷径,无非是要多看书、多看别人的代码、多写代码而已,但这些事说起来简单,要做好并不容易。亲爱的粉丝朋友,希望在未来的日子里,你能写出更多让自己和他人满意的代码,每天都能从 Python 中收获乐趣。原创 2024-06-24 19:52:59 · 193 阅读 · 0 评论 -
Python实践提升-开发大型项目
当开发功能与编写测试同步进行时,你会来回切换自己的角色,分别作为代码的设计者和使用者,不断从代码里找出问题,调整设计。要开发一个成功的大型项目(注意:这里的“成功”不是商业意义上的,而是工程意义上的),你不光需要 Linter 工具和单元测试,还需注重与团队成员间的沟通,积极推行代码审查,营造更好的合作氛围,等等。但如今,事情发生了很多变化。举个例子,假如在应用代码里,你提交了 10 行非常相似的重复代码,那么这些代码几乎一定会在代码审查阶段,被其他同事作为烂代码指出来,最后它们非得抽象成函数不可。原创 2024-06-24 19:48:26 · 737 阅读 · 0 评论 -
Python实践提升-数据模型与描述符
Python实践提升-数据模型与描述符在 Python 中,数据模型(data model)是个非常重要的概念。我们已经知道,Python 里万物皆对象,任何数据都通过对象来表达。而在用对象建模数据时,肯定不能毫无章法,一定需要一套严格的规则。我们常说的数据模型(或者叫对象模型)就是这套规则。假如把 Python 语言看作一个框架,数据模型就是这个框架的说明书。数据模型描述了框架如何工作,创建怎样的对象才能更好地融入 Python 这个框架。也许你还不清楚,数据模型究竟如何影响我们的代码。为此,我们从一个原创 2024-06-24 19:29:07 · 993 阅读 · 0 评论 -
Python实践提升-面向对象设计原则(下)
同时,对于 LocalHNWebPage 类来说,它也不需要再纠结如何实现 get_generated_at() 方法,而只要认准那个只返回文本的 ContentOnlyHNWebPage 接口,实现其中的 get_text() 方法就行,如图 11-5 所示。类似的情况还有许多,比如一个负责发短信的函数,本身只需要两个参数:电话号码(phone_number)和用户姓名(username),但是函数依赖了整个用户对象(User),里面包含了几十个它根本不关心的其他字段和方法。原创 2024-06-24 19:09:19 · 1044 阅读 · 0 评论 -
Python实践提升-面向对象设计原则(上)
假如我现在要写另一个和 Hacker News 有关的脚本,需要复用 HNTopPostsSpider 类的抓取和解析逻辑,会发现这件事根本做不到,因为我必须提供一个莫名其妙的文件对象给 HNTopPostsSpider 类才行。没过几天,我的兴趣就发生了变化,我突然觉得,除了 GitHub 以外,来自 Bloomberg3 的内容也很有意思。比如,某天我为了适配 Hacker News 站点的新样式,调整了页面的解析逻辑,却发现输出的文件内容全被破坏了。而在所有的设计原则中,SOLID 最为有名。原创 2024-06-24 18:50:05 · 784 阅读 · 0 评论 -
Python实践提升-面向对象编程
和那些严格的面向对象语言不同,在 Python 中,“面向对象”不必特别纯粹,你不必严格套用经典的 23 种设计模式,开口“抽象工厂”,闭口“命令模式”,只通过类来实现所有功能。在写代码时,如果你在原有的面向对象代码上,撒上一点儿函数作为调味品,就会发生奇妙的化学反应。虽然我在课堂上学到的“继承”,作为一个“基本特征”,似乎显得“人畜无害”、很好掌握,不过在之后的十几年编程生涯里,在写过和看过太多糟糕的代码后,我发现“继承”虽然是一个基本概念,但它同时也是面向对象设计中最容易做错的事情之一。原创 2024-06-24 11:29:21 · 733 阅读 · 0 评论 -
Python实践提升-装饰器
但如果你查看 Click 包的源码,就会发现 Click 的所有装饰器都在一个不到 400 行代码的 decorators.py 文件中,里面的大部分装饰器的代码不超过 10 行,如代码清单 8-12 所示。“动态修改函数”的能力,其实并不是由装饰器提供的。在设计新的装饰器时,你可以先参考上面的常见装饰器功能列表,琢磨琢磨自己的设计是否能很好地发挥装饰器的优势。为此我们需要先修改类的实例化方法,增加额外的参数,再定义一个新函数,由它来负责基于类创建新的可调用对象,这个新函数同时也是会被实际使用的装饰器。原创 2024-06-24 11:06:31 · 923 阅读 · 0 评论 -
Python实践提升-函数
但假如你在调用 partial_obj 对象时提供了额外参数,前者就会首先将本次调用参数和构造 partial_obj 时的参数进行合并,然后将合并后的参数透传给原始函数 func 处理,也就是说,partial_obj(bar=2) 与 func(True, foo=1, bar=2) 效果相同。但是,如果你使用下面这种“函数套函数”的方式,在外层函数执行结束后,返回内嵌函数,后者就可以继续访问前者的局部变量,形成了一个“闭包”结构,如代码清单 7-4 所示。换句话说,纯函数是一种无状态的函数。原创 2024-06-24 10:53:57 · 939 阅读 · 0 评论 -
Python实践提升-循环与可迭代对象
循环”是一个非常有趣的概念。在生活中,循环代表无休止地重复某件事,比如一直播放同一首歌就叫“单曲循环”。当某件事重复太多次以后,人们就很容易感到乏味,所以哪怕再好听的旷世名曲,也没人愿意连续听上一百遍。虽然人会对循环感到乏味,计算机却丝毫没有这个问题。程序员的主要任务之一,就是利用循环的概念,用极少的指令驱使计算机不知疲倦地完成繁重的计算任务。试想一下,假如不使用循环,从一个包含一万个数字的列表里找到数字 42 的位置,会是一件多么令人抓狂的任务。原创 2024-06-24 10:33:06 · 880 阅读 · 0 评论 -
Python实践提升-异常与错误处理
else 这个词,字面意义是“否则”,但当它紧随着 try 和 except 出现时,你其实很难分辨它到底代表哪一种“否则”——到底是有异常时的“否则”,还是没异常时的“否则”。另外,EAFP 风格的代码通常性能也更好。unset 命令的例子体现出了一种程序设计技巧:在设计 API 时,如果稍微调整一下思考问题的角度,修改 API 的抽象定义,那么那些原本需要处理的错误,也许就会神奇地消失。在设计这个命令时,作者认为当人们用 unset 删除一个不存在的变量时,一定是不正常的,程序自然应该抛出一个错误。原创 2024-06-24 00:31:39 · 661 阅读 · 0 评论 -
Python实践提升-条件分支控制流
此时如果转换一下思路,这些直译的分支代码也许能完全消失,代码会变得更紧凑、更具扩展性,整个编码过程更像一种巧妙的“意译”,而非“直译”。“提前返回”指的是:当你在编写分支时,首先找到那些会中断执行的条件,把它们移到函数的最前面,然后在分支里直接使用 return 或 raise 结束执行。不过,虽然这个工具实现了我最初设想的功能,在它的源码里却藏着两大段可以简化的条件分支代码。这样能为程序节约可观的内存。当你在编写条件分支时,请多多思考这些分支背后所代表的深层需求,寻找简化它们的办法,进而写出更好的代码。原创 2024-06-24 00:05:32 · 792 阅读 · 0 评论 -
Python实践提升-容器类型
是一种特殊的字典类型。这种结构最大的一个特点是,当你在数组中间插入新成员时,该成员之后的其他成员都需要移动位置,该操作的平均时间复杂度是 O(n)。有时,我们需要修改字典中某个可能不存在的键,比如在下面的代码里,我需要往字典 d 的 items 键里追加新值,但 d[‘items’] 可能根本就不存在。在之前的代码里,有许多有关字典的零碎操作,比如求和、对 .items() 排序等,现在它们全都可以封装到 PerfLevelDict 类里,代码逻辑不再是东一块、西一块,而是全部由一个数据类搞定。原创 2024-06-23 21:55:04 · 907 阅读 · 0 评论 -
Python实践提升-数值与字符串
小 R 在心里问自己。在 Python 2.2 及之前的版本里,字符串拼接操作确实很慢,这正是由“不可变对象”和“内存分配”导致的,跟我最早看到的说法一致。答案是“有的”,它们就是 float(“inf”) 和 float(“-inf”)。计算机是一个二进制的世界,它能表示的所有数字,都是通过 0 和 1 两个数模拟而来的(比如二进制的 110 代表十进制的 6)。(1) 字符串:我们最常挂在嘴边的“普通字符串”,有时也被称为文本(text),是给人看的,对应 Python 中的字符串(str)类型。原创 2024-06-23 20:56:39 · 810 阅读 · 0 评论 -
Python实践提升-变量与注释
比如在上面的代码里,upgrade_to_level3(user) 函数已经通过自己的名称、文档表明了其目的,那在函数内部,我们完全可以把 how_many_points_needed_for_user_level3 直接删减成 level3_points。当我们看到一段代码时,最先注意到的,不是代码有几层循环,用了什么模式,而是变量与注释,因为它们是代码里最接近自然语言的东西,最容易被大脑消化、理解。这时,他最不愿意做的事,就是回过头去补写函数的接口注释,即便写了,也只是草草对付了事。原创 2024-06-23 20:15:34 · 1009 阅读 · 0 评论