-
+
@@ -20,29 +20,28 @@ Python 语言自身的内部实现细节也与这些容器类型息息相关。
### 内容目录
- [Python 工匠:容器的门道](#python-工匠容器的门道)
- - [序言](#序言)
- - [内容目录](#内容目录)
- - [当我们谈论容器时,我们在谈些什么?](#当我们谈论容器时我们在谈些什么)
- - [底层看容器](#底层看容器)
- - [写更快的代码](#写更快的代码)
- - [1. 避免频繁扩充列表/创建新列表](#1-避免频繁扩充列表创建新列表)
- - [2. 在列表头部操作多的场景使用 deque 模块](#2-在列表头部操作多的场景使用-deque-模块)
- - [3. 使用集合/字典来判断成员是否存在](#3-使用集合字典来判断成员是否存在)
- - [高层看容器](#高层看容器)
- - [写扩展性更好的代码](#写扩展性更好的代码)
- - [面向容器接口编程](#面向容器接口编程)
- - [常用技巧](#常用技巧)
- - [1. 使用元组改善分支代码](#1-使用元组改善分支代码)
- - [2. 在更多地方使用动态解包](#2-在更多地方使用动态解包)
- - [3. 使用 next() 函数](#3-使用-next-函数)
- - [4. 使用有序字典来去重](#4-使用有序字典来去重)
- - [常见误区](#常见误区)
- - [1. 当心那些已经枯竭的迭代器](#1-当心那些已经枯竭的迭代器)
- - [2. 别在循环体内修改被迭代对象](#2-别在循环体内修改被迭代对象)
- - [总结](#总结)
- - [系列其他文章](#系列其他文章)
- - [注解](#注解)
-
+ - [序言](#序言)
+ - [内容目录](#内容目录)
+ - [当我们谈论容器时,我们在谈些什么?](#当我们谈论容器时我们在谈些什么)
+ - [底层看容器](#底层看容器)
+ - [写更快的代码](#写更快的代码)
+ - [1. 避免频繁扩充列表/创建新列表](#1-避免频繁扩充列表创建新列表)
+ - [2. 在列表头部操作多的场景使用 deque 模块](#2-在列表头部操作多的场景使用-deque-模块)
+ - [3. 使用集合/字典来判断成员是否存在](#3-使用集合字典来判断成员是否存在)
+ - [高层看容器](#高层看容器)
+ - [写扩展性更好的代码](#写扩展性更好的代码)
+ - [面向容器接口编程](#面向容器接口编程)
+ - [常用技巧](#常用技巧)
+ - [1. 使用元组改善分支代码](#1-使用元组改善分支代码)
+ - [2. 在更多地方使用动态解包](#2-在更多地方使用动态解包)
+ - [3. 使用 next() 函数](#3-使用-next-函数)
+ - [4. 使用有序字典来去重](#4-使用有序字典来去重)
+ - [常见误区](#常见误区)
+ - [1. 当心那些已经枯竭的迭代器](#1-当心那些已经枯竭的迭代器)
+ - [2. 别在循环体内修改被迭代对象](#2-别在循环体内修改被迭代对象)
+ - [总结](#总结)
+ - [系列其他文章](#系列其他文章)
+ - [注解](#注解)
### 当我们谈论容器时,我们在谈些什么?
@@ -53,7 +52,6 @@ Python 语言自身的内部实现细节也与这些容器类型息息相关。
下面,让我们一起站在这两个不同的层面上,重新认识容器。
-
## 底层看容器
Python 是一门高级编程语言,**它所提供的内置容器类型,都是经过高度封装和抽象后的结果**。和“链表”、“红黑树”、“哈希表”这些名字相比,所有 Python 内建类型的名字,都只描述了这个类型的功能特点,其他人完全没法只通过这些名字了解它们的哪怕一丁点内部细节。
@@ -112,7 +110,7 @@ def validate_name(name):
```
> Hint: 强烈建议阅读 [TimeComplexity - Python Wiki](https://wiki.python.org/moin/TimeComplexity),了解更多关于常见容器类型的时间复杂度相关内容。
->
+>
> 如果你对字典的实现细节感兴趣,也强烈建议观看 Raymond Hettinger 的演讲 [Modern Dictionaries(YouTube)](https://www.youtube.com/watch?v=p33CVV29OG8&t=1403s)
## 高层看容器
@@ -316,6 +314,7 @@ user = {**{"name": "piglei"}, **{"movies": ["Fight Club"]}}
除此之外,你还可以在普通赋值语句中使用 `*` 运算符来动态地解包可迭代对象。如果你想详细了解相关内容,可以阅读下面推荐的 PEP。
> Hint:推进动态解包场景扩充的两个 PEP:
+>
> - [PEP 3132 -- Extended Iterable Unpacking | Python.org](https://www.python.org/dev/peps/pep-3132/)
> - [PEP 448 -- Additional Unpacking Generalizations | Python.org](https://www.python.org/dev/peps/pep-0448/)
@@ -350,7 +349,7 @@ print(next(i for i in numbers if i % 2 == 0))
```
> Hint: 在 Python 3.6 中,默认的字典类型修改了实现方式,已经变成有序的了。并且在 Python 3.7 中,该功能已经从 **语言的实现细节** 变成了为 **可依赖的正式语言特性**。
->
+>
> 但是我觉得让整个 Python 社区习惯这一点还需要一些时间,毕竟目前“字典是无序的”还是被印在无数本 Python 书上。所以,我仍然建议在一切需要有序字典的地方使用 OrderedDict。
## 常见误区
@@ -374,7 +373,7 @@ for number in numbers:
而且不光是生成器表达式,Python 3 里的 map、filter 内建函数也都有一样的特点。忽视这个特点很容易导致代码中出现一些难以察觉的 Bug。
-Instagram 就在项目从 Python 2 到 Python 3 的迁移过程中碰到了这个问题。它们在 PyCon 2017 上分享了对付这个问题的故事。访问文章 [Instagram 在 PyCon 2017 的演讲摘要](https://www.zlovezl.cn/articles/instagram-pycon-2017/),搜索“迭代器”可以查看详细内容。
+Instagram 就在项目从 Python 2 到 Python 3 的迁移过程中碰到了这个问题。它们在 PyCon 2017 上分享了对付这个问题的故事。访问文章 [Instagram 在 PyCon 2017 的演讲摘要](https://www.piglei.com/articles/instagram-pycon-2017/),搜索“迭代器”可以查看详细内容。
### 2. 别在循环体内修改被迭代对象
@@ -422,9 +421,9 @@ print(numbers)
## 系列其他文章
- [所有文章索引 [Github]](https://github.com/piglei/one-python-craftsman)
-- [Python 工匠:善用变量改善代码质量](https://www.zlovezl.cn/articles/python-using-variables-well/)
-- [Python 工匠:编写条件分支代码的技巧](https://www.zlovezl.cn/articles/python-else-block-secrets/)
-- [Python 工匠:使用数字与字符串的技巧](https://www.zlovezl.cn/articles/tips-on-numbers-and-strings/)
+- [Python 工匠:善用变量改善代码质量](https://www.piglei.com/articles/python-using-variables-well/)
+- [Python 工匠:编写条件分支代码的技巧](https://www.piglei.com/articles/python-else-block-secrets/)
+- [Python 工匠:使用数字与字符串的技巧](https://www.piglei.com/articles/tips-on-numbers-and-strings/)
## 注解
@@ -432,4 +431,3 @@ print(numbers)
2.
Python 里没有类似其他编程语言里的“Interface 接口”类型,只有类似的“抽象类”概念。为了表达方便,后面的内容均统一使用“接口”来替代“抽象类”。
3.
有没有只实现了 Mapping 但又不是 MutableMapping 的类型?试试 [MappingProxyType({})](https://docs.python.org/3/library/types.html#types.MappingProxyType)
4.
有没有只实现了 Set 但又不是 MutableSet 的类型?试试 [frozenset()](https://docs.python.org/3/library/stdtypes.html#frozenset)
-
diff --git a/zh_CN/5-function-returning-tips.md b/zh_CN/5-function-returning-tips.md
index 9e27fd8..c6f597c 100644
--- a/zh_CN/5-function-returning-tips.md
+++ b/zh_CN/5-function-returning-tips.md
@@ -5,7 +5,7 @@
> 这是 “Python 工匠”系列的第 5 篇文章。[[查看系列所有文章]](https://github.com/piglei/one-python-craftsman)
-
+
毫无疑问,函数是 Python 语言里最重要的概念之一。在编程时,我们将真实世界里的大问题分解为小问题,然后通过一个个函数交出答案。函数既是重复代码的克星,也是对抗代码复杂度的最佳武器。
@@ -23,22 +23,22 @@ Python 函数通过调用 `return` 语句来返回结果。使用 `return value`
### 内容目录
- [Python 工匠:让函数返回结果的技巧](#python-工匠让函数返回结果的技巧)
- - [序言](#序言)
- - [Python 的函数返回方式](#python-的函数返回方式)
- - [内容目录](#内容目录)
- - [编程建议](#编程建议)
- - [1. 单个函数不要返回多种类型](#1-单个函数不要返回多种类型)
- - [2. 使用 partial 构造新函数](#2-使用-partial-构造新函数)
- - [3. 抛出异常,而不是返回结果与错误](#3-抛出异常而不是返回结果与错误)
- - [4. 谨慎使用 None 返回值](#4-谨慎使用-none-返回值)
- - [1. 作为操作类函数的默认返回值](#1-作为操作类函数的默认返回值)
- - [2. 作为某些“意料之中”的可能没有的值](#2-作为某些意料之中的可能没有的值)
- - [3. 作为调用失败时代表“错误结果”的值](#3-作为调用失败时代表错误结果的值)
- - [5. 合理使用“空对象模式”](#5-合理使用空对象模式)
- - [6. 使用生成器函数代替返回列表](#6-使用生成器函数代替返回列表)
- - [7. 限制递归的使用](#7-限制递归的使用)
- - [总结](#总结)
- - [附录](#附录)
+ - [序言](#序言)
+ - [Python 的函数返回方式](#python-的函数返回方式)
+ - [内容目录](#内容目录)
+ - [编程建议](#编程建议)
+ - [1. 单个函数不要返回多种类型](#1-单个函数不要返回多种类型)
+ - [2. 使用 partial 构造新函数](#2-使用-partial-构造新函数)
+ - [3. 抛出异常,而不是返回结果与错误](#3-抛出异常而不是返回结果与错误)
+ - [4. 谨慎使用 None 返回值](#4-谨慎使用-none-返回值)
+ - [1. 作为操作类函数的默认返回值](#1-作为操作类函数的默认返回值)
+ - [2. 作为某些“意料之中”的可能没有的值](#2-作为某些意料之中的可能没有的值)
+ - [3. 作为调用失败时代表“错误结果”的值](#3-作为调用失败时代表错误结果的值)
+ - [5. 合理使用“空对象模式”](#5-合理使用空对象模式)
+ - [6. 使用生成器函数代替返回列表](#6-使用生成器函数代替返回列表)
+ - [7. 限制递归的使用](#7-限制递归的使用)
+ - [总结](#总结)
+ - [附录](#附录)
## 编程建议
@@ -161,12 +161,10 @@ def create_for_input():
- 虽然我在这里鼓励使用异常,但“异常”总是会无法避免的让人 **感到惊讶**,所以,最好在函数文档里说明可能抛出的异常类型
- 异常不同于返回值,它在被捕获前会不断往调用栈上层汇报。所以 `create_item` 的一级调用方完全可以省略异常处理,交由上层处理。这个特点给了我们更多的灵活性,但同时也带来了更大的风险。
-
> Hint:如何在编程语言里处理错误,是一个至今仍然存在争议的主题。比如像上面不推荐的多返回值方式,正是缺乏异常的 Go 语言中最核心的错误处理机制。另外,即使是异常机制本身,不同编程语言之间也存在着差别。
->
+>
> 异常,或是不异常,都是由语言设计者进行多方取舍后的结果,更多时候不存在绝对性的优劣之分。**但是,单就 Python 语言而言,使用异常来表达错误无疑是更符合 Python 哲学,更应该受到推崇的。**
-
### 4. 谨慎使用 None 返回值
`None` 值通常被用来表示 **“某个应该存在但是缺失的东西”**,它在 Python 里是独一无二的存在。很多编程语言里都有与 None 类似的设计,比如 JavaScript 里的 `null`、Go 里的 `nil` 等。因为 None 所拥有的独特 *虚无* 气质,它经常被作为函数返回值使用。
@@ -368,7 +366,7 @@ def foo_func(items):
yield item
```
-我在 [系列第 4 篇文章“容器的门道”](https://www.zlovezl.cn/articles/mastering-container-types/) 里详细分析过这个模式,更多细节可以访问文章,搜索 “写扩展性更好的代码” 查看。
+我在 [系列第 4 篇文章“容器的门道”](https://www.piglei.com/articles/mastering-container-types/) 里详细分析过这个模式,更多细节可以访问文章,搜索 “写扩展性更好的代码” 查看。
### 7. 限制递归的使用
@@ -401,14 +399,11 @@ def foo_func(items):
## 附录
- 题图来源: Dominik Scythe on Unsplash
-- 更多系列文章地址:https://github.com/piglei/one-python-craftsman
+- 更多系列文章地址:
系列其他文章:
- [所有文章索引 [Github]](https://github.com/piglei/one-python-craftsman)
-- [Python 工匠:善用变量改善代码质量](https://www.zlovezl.cn/articles/python-using-variables-well/)
-- [Python 工匠:编写条件分支代码的技巧](https://www.zlovezl.cn/articles/python-else-block-secrets/)
-- [Python 工匠:使用数字与字符串的技巧](https://www.zlovezl.cn/articles/tips-on-numbers-and-strings/)
-
-
-
+- [Python 工匠:善用变量改善代码质量](https://www.piglei.com/articles/python-using-variables-well/)
+- [Python 工匠:编写条件分支代码的技巧](https://www.piglei.com/articles/python-else-block-secrets/)
+- [Python 工匠:使用数字与字符串的技巧](https://www.piglei.com/articles/tips-on-numbers-and-strings/)
diff --git a/zh_CN/6-three-rituals-of-exceptions-handling.md b/zh_CN/6-three-rituals-of-exceptions-handling.md
index fffe99a..ab67108 100644
--- a/zh_CN/6-three-rituals-of-exceptions-handling.md
+++ b/zh_CN/6-three-rituals-of-exceptions-handling.md
@@ -5,7 +5,7 @@
> 这是 “Python 工匠”系列的第 6 篇文章。[[查看系列所有文章]](https://github.com/piglei/one-python-craftsman)
-
+
如果你用 Python 编程,那么你就无法避开异常,因为异常在这门语言里无处不在。打个比方,当你在脚本执行时按 `ctrl+c` 退出,解释器就会产生一个 `KeyboardInterrupt` 异常。而 `KeyError`、`ValueError`、`TypeError` 等更是日常编程里随处可见的老朋友。
@@ -15,7 +15,7 @@
在这篇文章里,我会分享与异常处理相关的 3 个好习惯。继续阅读前,我希望你已经了解了下面这些知识点:
- 异常的基本语法与用法*(建议阅读官方文档 [“Errors and Exceptions”](https://docs.python.org/3.6/tutorial/errors.html))*
-- 为什么要使用异常代替错误返回*(建议阅读[《让函数返回结果的技巧》](https://www.zlovezl.cn/articles/function-returning-tips/))*
+- 为什么要使用异常代替错误返回*(建议阅读[《让函数返回结果的技巧》](https://www.piglei.com/articles/function-returning-tips/))*
- 为什么在写 Python 时鼓励使用异常 *(建议阅读 [“Write Cleaner Python: Use Exceptions”](https://jeffknupp.com/blog/2013/02/06/write-cleaner-python-use-exceptions/))*
## 三个好习惯
@@ -294,7 +294,7 @@ def upload_avatar(request):
```
> Hint:建议阅读 [PEP 343 -- The "with" Statement | Python.org](https://www.python.org/dev/peps/pep-0343/),了解与上下文管理器有关的更多知识。
->
+>
> 模块 [contextlib](https://docs.python.org/3/library/contextlib.html) 也提供了非常多与编写上下文管理器相关的工具函数与样例。
## 总结
@@ -314,13 +314,11 @@ def upload_avatar(request):
## 附录
- 题图来源: Photo by Bernard Hermant on Unsplash
-- 更多系列文章地址:https://github.com/piglei/one-python-craftsman
+- 更多系列文章地址:
系列其他文章:
- [所有文章索引 [Github]](https://github.com/piglei/one-python-craftsman)
-- [Python 工匠:善用变量改善代码质量](https://www.zlovezl.cn/articles/python-using-variables-well/)
-- [Python 工匠:编写条件分支代码的技巧](https://www.zlovezl.cn/articles/python-else-block-secrets/)
-- [Python 工匠:让程序返回结果的技巧](https://www.zlovezl.cn/articles/function-returning-tips/)
-
-
+- [Python 工匠:善用变量改善代码质量](https://www.piglei.com/articles/python-using-variables-well/)
+- [Python 工匠:编写条件分支代码的技巧](https://www.piglei.com/articles/python-else-block-secrets/)
+- [Python 工匠:让程序返回结果的技巧](https://www.piglei.com/articles/function-returning-tips/)
diff --git a/zh_CN/7-two-tips-on-loop-writing.md b/zh_CN/7-two-tips-on-loop-writing.md
index c7578c3..8db9317 100644
--- a/zh_CN/7-two-tips-on-loop-writing.md
+++ b/zh_CN/7-two-tips-on-loop-writing.md
@@ -5,7 +5,7 @@
> 这是 “Python 工匠”系列的第 7 篇文章。[[查看系列所有文章]](https://github.com/piglei/one-python-craftsman)
-
+
循环是一种常用的程序控制结构。我们常说,机器相比人类的最大优点之一,就是机器可以不眠不休的重复做某件事情,但人却不行。而**“循环”**,则是实现让机器不断重复工作的关键概念。
@@ -52,7 +52,7 @@ for i, name in enumerate(names):
使用修饰函数处理可迭代对象,可以在各种方面影响循环代码。而要找到合适的例子来演示这个方法,并不用去太远,内置模块 [itertools](https://docs.python.org/3.6/library/itertools.html) 就是一个绝佳的例子。
-简单来说,itertools 是一个包含很多面向可迭代对象的工具函数集。我在之前的系列文章[《容器的门道》](https://www.zlovezl.cn/articles/mastering-container-types/)里提到过它。
+简单来说,itertools 是一个包含很多面向可迭代对象的工具函数集。我在之前的系列文章[《容器的门道》](https://www.piglei.com/articles/mastering-container-types/)里提到过它。
如果要学习 itertools,那么 [Python 官方文档](https://docs.python.org/3.6/library/itertools.html) 是你的首选,里面有非常详细的模块相关资料。但在这篇文章里,侧重点将和官方文档稍有不同。我会通过一些常见的代码场景,来详细解释它是如何改善循环代码的。
@@ -73,7 +73,6 @@ def find_twelve(num_list1, num_list2, num_list3):
对于这种需要嵌套遍历多个对象的多层循环代码,我们可以使用 [product()](https://docs.python.org/3.6/library/itertools.html#itertools.product) 函数来优化它。`product()` 可以接收多个可迭代对象,然后根据它们的笛卡尔积不断生成结果。
-
```python
from itertools import product
@@ -311,14 +310,11 @@ def notify_nonsleep_users_in_last_30days():
## 附录
- 题图来源: Photo by Lai man nung on Unsplash
-- 更多系列文章地址:https://github.com/piglei/one-python-craftsman
+- 更多系列文章地址:
系列其他文章:
- [所有文章索引 [Github]](https://github.com/piglei/one-python-craftsman)
-- [Python 工匠:容器的门道](https://www.zlovezl.cn/articles/mastering-container-types/)
-- [Python 工匠:编写条件分支代码的技巧](https://www.zlovezl.cn/articles/python-else-block-secrets/)
-- [Python 工匠:异常处理的三个好习惯](https://www.zlovezl.cn/articles/three-rituals-of-exceptions-handling/)
-
-
-
+- [Python 工匠:容器的门道](https://www.piglei.com/articles/mastering-container-types/)
+- [Python 工匠:编写条件分支代码的技巧](https://www.piglei.com/articles/python-else-block-secrets/)
+- [Python 工匠:异常处理的三个好习惯](https://www.piglei.com/articles/three-rituals-of-exceptions-handling/)
diff --git a/zh_CN/8-tips-on-decorators.md b/zh_CN/8-tips-on-decorators.md
index 9517c23..2e0e93c 100644
--- a/zh_CN/8-tips-on-decorators.md
+++ b/zh_CN/8-tips-on-decorators.md
@@ -5,7 +5,7 @@
> 这是 “Python 工匠”系列的第 8 篇文章。[[查看系列所有文章]](https://github.com/piglei/one-python-craftsman)
-
+
装饰器 *(Decorator)* 是 Python 里的一种特殊工具,它为我们提供了一种在函数外部修改函数的灵活能力。它有点像一顶画着独一无二 `@` 符号的神奇帽子,只要将它戴在函数头顶上,就能悄无声息的改变函数本身的行为。
@@ -345,17 +345,14 @@ def decorated(*args, **kwargs):
[<<<上一篇【7.编写地道循环的两个建议】](7-two-tips-on-loop-writing.md)
-
## 附录
- 题图来源: Photo by Clem Onojeghuo on Unsplash
-- 更多系列文章地址:https://github.com/piglei/one-python-craftsman
+- 更多系列文章地址:
系列其他文章:
- [所有文章索引 [Github]](https://github.com/piglei/one-python-craftsman)
-- [Python 工匠:编写条件分支代码的技巧](https://www.zlovezl.cn/articles/python-else-block-secrets/)
-- [Python 工匠:异常处理的三个好习惯](https://www.zlovezl.cn/articles/three-rituals-of-exceptions-handling/)
-- [Python 工匠:编写地道循环的两个建议](https://www.zlovezl.cn/articles/two-tips-on-loop-writing/)
-
-
+- [Python 工匠:编写条件分支代码的技巧](https://www.piglei.com/articles/python-else-block-secrets/)
+- [Python 工匠:异常处理的三个好习惯](https://www.piglei.com/articles/three-rituals-of-exceptions-handling/)
+- [Python 工匠:编写地道循环的两个建议](https://www.piglei.com/articles/two-tips-on-loop-writing/)
diff --git a/zh_CN/9-a-story-on-cyclic-imports.md b/zh_CN/9-a-story-on-cyclic-imports.md
index 86e30c0..0ef3664 100644
--- a/zh_CN/9-a-story-on-cyclic-imports.md
+++ b/zh_CN/9-a-story-on-cyclic-imports.md
@@ -5,7 +5,7 @@
> 这是 “Python 工匠”系列的第 9 篇文章。[[查看系列所有文章]](https://github.com/piglei/one-python-craftsman)
-
+
模块(Module)是我们用来组织 Python 代码的基本单位。很多功能强大的复杂站点,都由成百上千个独立模块共同组成。
@@ -125,7 +125,7 @@ ImportError: cannot import name 'User' from 'fancy_site.users' (.../fancy_site/u
如此一来,整个模块依赖关系成为了环状,程序自然也就没法执行下去了。
-![modules_before](https://www.zlovezl.cn/static/uploaded/2019/05/modules_before.png)
+![modules_before](https://www.piglei.com/static/uploaded/2019/05/modules_before.png)
不过,没有什么问题能够难倒一个可以正常访问 Google 的程序员。小 R 随便上网一搜,发现这样的问题很好解决。因为 Python 的 import 语句非常灵活,他只需要 **把在 users 模块内导入 send_sms 函数的语句挪到 `add_notification` 方法内,延缓 import 语句的执行就行啦。**
@@ -157,7 +157,7 @@ from .msg_utils import send_sms
新的模块依赖关系如下图所示:
-![modules_afte](https://www.zlovezl.cn/static/uploaded/2019/05/modules_after.png)
+![modules_afte](https://www.piglei.com/static/uploaded/2019/05/modules_after.png)
在新的模块结构中,整个项目被整齐的分为三层,模块间的依赖关系也变得只有**单向流动**。之前在函数内部 `import` 的“延迟导入”技巧,自然也就没有用武之地了。
@@ -185,14 +185,11 @@ from .msg_utils import send_sms
## 附录
- 题图来源: Photo by Ricardo Gomez Angel on Unsplash
-- 更多系列文章地址:https://github.com/piglei/one-python-craftsman
+- 更多系列文章地址:
系列其他文章:
- [所有文章索引 [Github]](https://github.com/piglei/one-python-craftsman)
-- [Python 工匠:编写条件分支代码的技巧](https://www.zlovezl.cn/articles/python-else-block-secrets/)
-- [Python 工匠:异常处理的三个好习惯](https://www.zlovezl.cn/articles/three-rituals-of-exceptions-handling/)
-- [Python 工匠:编写地道循环的两个建议](https://www.zlovezl.cn/articles/two-tips-on-loop-writing/)
-
-
-
+- [Python 工匠:编写条件分支代码的技巧](https://www.piglei.com/articles/python-else-block-secrets/)
+- [Python 工匠:异常处理的三个好习惯](https://www.piglei.com/articles/three-rituals-of-exceptions-handling/)
+- [Python 工匠:编写地道循环的两个建议](https://www.piglei.com/articles/two-tips-on-loop-writing/)