Python工匠 | 全书要点汇总(1)

简介: 前言Python前前后后我学了好几遍了,了解了Python中的许多用法,但都为快速入门之类的教程,基于“要干什么 --> 怎么做”的模式学习。而在动手编程的过程中,我常常感觉心有所惑,于是决定更系统地去学习、了解Python知识。

前言

Python前前后后我学了好几遍了,了解了Python中的许多用法,但都为快速入门之类的教程,基于“要干什么 --> 怎么做”的模式学习。而在动手编程的过程中,我常常感觉心有所惑,于是决定更系统地去学习、了解Python知识。

但通过什么学习呢,视频,还是书籍?我想了想,还是选择了书,书的知识体系往往更加系统和详细。我打开了豆瓣,看看有哪些评分比较高的书。我从中挑出了几本:《Python编程 从入门到实践》、《流畅的Python》、《Python工匠 案例、技巧与工程实践》、《Effective Python》,对比了它们的目录,最终选择了这本Python工匠。


读起来体验感还不错,如果Python语言是把斧子,那有的入门书籍就像是买斧子送的产品说明书,而这本书则像是李逵的《黑风斧法》。(想不出合适的比喻了,就这样吧 )


这本书我7天看了第一遍,感觉整体还比较好懂,但从”第八章——装饰器“开始,难度有所上升,读时留了一些还未理解的地方。


本文可在开发同时,快速回顾各种注意事项,审查自己的代码。

:以下内容完全摘自《Python工匠 案例、技巧与工程实践》 一书。

1 变量与注释

1、变量和注释决定第一印象

  • 变量和注释是代码里最接近自然语言的东西,它们的可读性非常重要。
  • 即使是同一个算法,变量和注释不一样,给人的感觉也会截然不同。

2、基础知识

  • Python的变量赋值语法非常灵活,可以使用*variables星号表达式灵活赋值。
  • 编写注释的两个要点:不要用来屏蔽代码,不要用来解释为什么。
  • 接口注释是为使用者而写,因此应该简明扼要地描述函数职责,而不必包含太多内部细节。
  • 可以使用Sphinx格式文档或类型注解给变量标明类型。

3、变量名字很重要

  • 给变量起名要遵循PEP8原则,代码的其他部分也同样如此。
  • 尽量给变量起描述性强的名字,但评价描述性也需要结合场景。
  • 在保证描述性的前提下,变量名的长度要尽量短。
  • 变量名要匹配它所表达的类型。
  • 可以使用一两个字母的超短名字,但注意不要过度使用。

4、代码组织技巧

  • 按照代码的职责来组织代码:让变量定义靠近使用。
  • 适当定义临时变量可以提升代码的可读性。
  • 不必要的变量会让代码显得冗长、啰嗦。
  • 同一个作用域内不要有太多变量,解决办法:提炼数据类、拆分函数。
  • 空行也是一种特殊的“注释”,适当的空行可以让代码更易读。

5、代码的可维护性技巧

  • 保持变量在两个方面的一致性:名字一致性和类型一致性。
  • 显式优于隐式:不要使用locals()批量获取变量。
  • 把接口注释当成一种函数设计工具:先写注释,后写代码。

2 数值与字符串

1、数值基础知识

  • Python的浮点数有精度问题,请使用Decimal对象做精确的小数运算。
  • 布尔类型是整型的子类型,布尔值可以当作0和1来使用。
  • 使用float('inf')无穷大可以简化边界处理逻辑。

2、字符串基础知识

字符串分为两类:str(给人阅读的文本类型)和bytes(给计算机阅读的二进制类型)

通过.encode()与.decode()可以在两种该字符串之间做转换

优先推荐的字符串格式化方式(从前往后):f-string、str.format()、C语言风格格式化

使用以r开头的字符串内置方法可以从右往左处理字符串,特定场景下可以派上用场

字符串拼接并不慢,不要因为性能原因害怕使用它

3、代码可读性技巧

  • 在定义数值字面量时,可以通过插入_字符来提升可读性
  • 不要出现“神奇”的字面量,使用常量或者枚举类型替换它们
  • 保留数学算式表达式不会影响性能,并且可以提升可读性
  • 使用textwrap.dedent()可以让多行字符串更好地融入代码

4、代码可维护性技巧

  • 当操作SQL语句等结构化字符串时,使用专有模块比裸处理的代码更易于维护
  • 使用Jinja2模板来代替字符串拼接操作

5、语言内部知识

  • 使用dis模块可以查看Python字节码,帮助我们理解内部原理
  • 使用timeit模块可以对Python代码方便地进行性能测试
  • Python语言进化得特别快,不要轻易被旧版本的“经验”所左右

3 容器类型

1、基础知识

  • 在进行函数调用时,传递的不是变量的值或者引用,而是变量所指对象的引用
  • Python内置类型分为可变与不可变两种,可变性会影响一些操作的行为,比如+=
  • 对于可变类型,必要时对其进行拷贝操作,能避免产生意料之外的影响
  • 常见的浅拷贝方式:copy.copy,推导式,切片操作

2、列表与元组

  • 使用enumerate可以在遍历列表的同时获取下标
  • 函数的多返回值其实是一个元组
  • 不存在元组推导式,但可以使用tuple来将生成器表达式转换为元组
  • 元组经常用来表示一些结构化的数据

3、字典与集合

  • 在Python3.7版本前,字典类型是无序的,之后变为保留数据的插入顺序
  • 使用OrderedDict可以在Python3.7以前的版本里获取有序字典
  • 只有可哈希的对象才能存入集合,或者作为字典的键使用
  • 使用有序字典OrderedDict可以快速实现有序去重
  • 使用fronzenset可以获得一个不可变的集合对象
  • 集合可以方便地进行集合运算,计算交集、并集
  • 不要通过集成dict来创建自定义字典类型

4、代码可读性技巧

  • 具名元组比普通元组可读性更强
  • 列表推导式可以更快速地完成遍历、过滤、处理以及构建新列表操作
  • 不要编写过于复杂的推导式,用朴实的代码代替就好
  • 不要把推导式当作代码量更少的循环,写普通循环就好

5、代码可维护性技巧

  • 当访问的字典键不存在时,可以选择捕获异常或先做判断,优先推荐捕获异常
  • 使用getsetdefault、带参数的pop方法可以贱货边界处理逻辑
  • 使用具名元组作为返回值,比普通元组更好扩展
  • 当字典键不存在时,使用defaultdict可以简化处理
  • 继承MutableMapping可以方便地创建自定义字典类,封装处理逻辑
  • 用生成器按需返回成员,比直接返回一个结果列表更灵活,也更省内存
  • 使用动态解包语法可以方便地合并字典
  • 不要再遍历列表的同时修改,否则会出现不可预期的结果

6、代码性能要点

  • 列表的底层实现决定了它的头部操作很慢,deque类型则没有这个问题
  • 当需要判断某个成员在容器中是否存在时,使用字典/集合更快

4 条件分支控制流

1、条件分支语句惯用写法

  • 不要显式地和布尔值作比较
  • 利用类型本身的布尔值规则,省略零值判断
  • not代表的否定逻辑移入表达式内部
  • 仅在需要判断某个对象是否式NoneTrueFalse时,使用is运算符

2、Python数据模型

  • 定义__len____bool__魔法方法,可以自定义对象的布尔值规则
  • 定义__eq__方法,可以修改对象在进行==运算时的行为

3、代码可读性技巧

  • 不同分支内容易出现重复或类似的代码,把它们抽到分支外可提升代码的可读性
  • 使用"德摩根定律"可以让有多重否定的表达式变得更容易理解

4、代码可维护性技巧

  • 尽可能让三元表达式保持简单
  • 扁平优于嵌套:使用“提前返回”优化代码里的多层分支嵌套
  • 当条件表达式变得特别复杂时,可以尝试封装新的函数和方法来简化
  • and的优先级比or高,不要忘记使用括号来让逻辑更清晰
  • 在使用or运算符替代条件分支时,请注意避开因布尔值运算导致的陷阱(?)

5、代码组织技巧

  • bisect模块可以用来优化范围类分支判断
  • 字典类型可以用来替代简单的条件分支语句
  • 尝试总结条件分支代码里的规律,用更精简、更易扩展的方式改写它们
  • 使用any()all()内置函数可以让条件表达式变得更加精简

5 异常与错误处理

1、基础知识

  • 一个try语句支持多个except子句,但请记得把更精确的异常类放在前面
  • try语句的else分支会在没有异常时执行,因此它可用来替代标记变量
  • 不带任何参数的raise语句会重复抛出当前异常
  • 上下文管理器经常用来处理异常,它最常见的用途是替代finally子句
  • 上下文管理器可以用来忽略某段代码里的异常
  • 使用@contextmanager装饰器可以轻松定义上下文管理器

2、错误处理与参数校验

  • 当你可以选择编写条件判断或异常捕获时,优先选异常捕获
  • 不要让函数返回错误信息,直接抛出自定义异常吧
  • 手动校验数据合法性非常烦琐,尽量使用专业模块来做这件事
  • 不要使用assert来做参数校验,用raise来替代它(?)
  • 处理错误需要付出额外成本,假如能通过设计避免它就再好不过了
  • 在设计API时,需要慎重考虑是否真的有必要抛出错误
  • 使用“空对象模式”能免去一些针对边界情况的错误处理工作

3、当你捕获异常时

  • 过于模糊和宽泛的异常捕获可能会让程序免于崩溃,但也可能会带来更大的麻烦
  • 异常捕获贵在精确,只捕获可能抛出异常的语句,只捕获可能的异常类型
  • 有时候,让程序提早崩溃未必是什么坏事
  • 完全忽略异常时风险非常高的行为,大多数情况下,至少记录一条错误日志

4、当你抛出异常时

  • 保证模块内抛出的异常与模块自身的抽象级别一致
  • 如果异常的抽象级别过高,把它替换为更低级的新异常
  • 如果异常的抽象级别过低,把它包装成更高级的异常
  • 不要让调用方用字符串匹配来判断异常种类,尽量提供可区分的异常

6 循环与可迭代对象

1、迭代与迭代器原理

  • 使用iter()函数会尝试获取一个迭代器对象
  • 使用next()函数会获取迭代器的下一个内容
  • 可以将for循环简单地理解为while循环加不断调用next()
  • 自定义迭代器需要实现__iter____next__两个魔法方法
  • 生成器对象是迭代器的一种
  • iter(callable, sentinel)可以基于可调用对象构造一个迭代器(?)

2、迭代器与可迭代对象

  • 迭代器和可迭代对象是不同的概念
  • 可迭代对象不一定是迭代器,但迭代器一定是可迭代对象
  • 对可迭代对象使用giter()会返回迭代器,迭代器则会返回它自身
  • 每个迭代器的被迭代过程是一次性的,可迭代对象则不一定
  • 可迭代对象只需要实现__iter__方法,而迭代器还需要额外实现__next__方法

3、代码可维护性技巧

  • 通过定义生成器函数来修饰可迭代对象,可以优化循环内部代码
  • itertools模块里有许多函数可以用来修饰可迭代对象
  • 生成器函数可以用来解耦循环代码,提升可复用性
  • 不要使用多个break,拆分为函数然后直接return更好
  • 使用next()函数有时可以完成一些意想不到的功能

4、文件操作知识

  • 使用标准做法读取文件内容,在处理没有换行符的大文件时会很慢
  • 调用file.read()方法可以解决读取大文件的性能问题

Python工匠 | 全书要点汇总(2):https://developer.aliyun.com/article/1407217?spm=a2c6h.13148508.setting.15.79f64f0ecKMDuK

相关文章
|
6月前
|
缓存 关系型数据库 测试技术
Python工匠 | 全书要点汇总(2)
7 函数 1、函数参数与返回相关基础知识 不要使用可变类型作为参数默认值,用None来代替 使用标记对象,可以严格区分函数调用时是否提供了某个参数
81 2
|
4月前
|
数据采集 机器学习/深度学习 运维
Python大佬耗费13年,始成400页《Python工匠》手册
Python 能干的事情实在太多了,掰着指头数有点不够用。 Web 开发、数据分析、网络爬虫、自动化运维、后台开发、机器学习....... 如果你知道主攻哪个方向,只需重点去学习。不过,不论哪个方向,Python 编程的核心知识都是需要掌握的。 但是今天咱们要讨论的一件事儿,是对于一些入门了的盆友,写了不少代码,一到面试就卡bug,又或者在项目中运用Python,代码不怎么样,却自我感觉良好,结果到处出漏洞,一堆的烂摊子。 我相信,这样的朋友肯定不少,可是目前市面上能帮助大家解决这种问题的书籍又非常稀缺,今天我就给大家推荐一本能帮助你解决燃煤之急的书籍。
|
设计模式 缓存 IDE
『Python 工匠』是什么?
『Python 工匠』这个系列文章,是我的一次小小尝试。它专注于分享 Python 编程中的一些偏『小』的东西。希望能够帮到每一位编程路上的匠人。 系列文章: • Python 工匠:善用变量改善代码质量 • Python 工匠:编写条件分支代码的技巧
98 0
|
1天前
|
存储 Python
Python编程入门:打造你的第一个程序
【10月更文挑战第39天】在数字时代的浪潮中,掌握编程技能如同掌握了一门新时代的语言。本文将引导你步入Python编程的奇妙世界,从零基础出发,一步步构建你的第一个程序。我们将探索编程的基本概念,通过简单示例理解变量、数据类型和控制结构,最终实现一个简单的猜数字游戏。这不仅是一段代码的旅程,更是逻辑思维和问题解决能力的锻炼之旅。准备好了吗?让我们开始吧!
|
1天前
|
机器学习/深度学习 人工智能 TensorFlow
人工智能浪潮下的自我修养:从Python编程入门到深度学习实践
【10月更文挑战第39天】本文旨在为初学者提供一条清晰的道路,从Python基础语法的掌握到深度学习领域的探索。我们将通过简明扼要的语言和实际代码示例,引导读者逐步构建起对人工智能技术的理解和应用能力。文章不仅涵盖Python编程的基础,还将深入探讨深度学习的核心概念、工具和实战技巧,帮助读者在AI的浪潮中找到自己的位置。
|
3天前
|
设计模式 算法 搜索推荐
Python编程中的设计模式:优雅解决复杂问题的钥匙####
本文将探讨Python编程中几种核心设计模式的应用实例与优势,不涉及具体代码示例,而是聚焦于每种模式背后的设计理念、适用场景及其如何促进代码的可维护性和扩展性。通过理解这些设计模式,开发者可以更加高效地构建软件系统,实现代码复用,提升项目质量。 ####
|
2天前
|
机器学习/深度学习 存储 算法
探索Python编程:从基础到高级应用
【10月更文挑战第38天】本文旨在引导读者从Python的基础知识出发,逐渐深入到高级编程概念。通过简明的语言和实际代码示例,我们将一起探索这门语言的魅力和潜力,理解它如何帮助解决现实问题,并启发我们思考编程在现代社会中的作用和意义。
|
1天前
|
机器学习/深度学习 数据挖掘 Python
Python编程入门——从零开始构建你的第一个程序
【10月更文挑战第39天】本文将带你走进Python的世界,通过简单易懂的语言和实际的代码示例,让你快速掌握Python的基础语法。无论你是编程新手还是想学习新语言的老手,这篇文章都能为你提供有价值的信息。我们将从变量、数据类型、控制结构等基本概念入手,逐步过渡到函数、模块等高级特性,最后通过一个综合示例来巩固所学知识。让我们一起开启Python编程之旅吧!
|
3天前
|
机器学习/深度学习 数据挖掘 开发者
Python编程入门:理解基础语法与编写第一个程序
【10月更文挑战第37天】本文旨在为初学者提供Python编程的初步了解,通过简明的语言和直观的例子,引导读者掌握Python的基础语法,并完成一个简单的程序。我们将从变量、数据类型到控制结构,逐步展开讲解,确保即使是编程新手也能轻松跟上。文章末尾附有完整代码示例,供读者参考和实践。
|
3天前
|
人工智能 数据挖掘 程序员
Python编程入门:从零到英雄
【10月更文挑战第37天】本文将引导你走进Python编程的世界,无论你是初学者还是有一定基础的开发者,都能从中受益。我们将从最基础的语法开始讲解,逐步深入到更复杂的主题,如数据结构、面向对象编程和网络编程等。通过本文的学习,你将能够编写出自己的Python程序,实现各种功能。让我们一起踏上Python编程之旅吧!