作者: andylin02
学习章节: 第10章 – 协作开发
关键词: 模块, 包, 相对导入, 绝对导入, 命名空间包, 虚拟环境, pipenv, 文档字符串, doctest, 项目结构
第10章思维导图:9条建议全景
#mermaid-svg-Ji8RWXTnFdoUP6PD{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-Ji8RWXTnFdoUP6PD .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-Ji8RWXTnFdoUP6PD .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-Ji8RWXTnFdoUP6PD .error-icon{fill:#552222;}#mermaid-svg-Ji8RWXTnFdoUP6PD .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-Ji8RWXTnFdoUP6PD .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-Ji8RWXTnFdoUP6PD .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-Ji8RWXTnFdoUP6PD .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-Ji8RWXTnFdoUP6PD .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-Ji8RWXTnFdoUP6PD .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-Ji8RWXTnFdoUP6PD .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-Ji8RWXTnFdoUP6PD .marker{fill:#333333;stroke:#333333;}#mermaid-svg-Ji8RWXTnFdoUP6PD .marker.cross{stroke:#333333;}#mermaid-svg-Ji8RWXTnFdoUP6PD svg{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-Ji8RWXTnFdoUP6PD p{margin:0;}#mermaid-svg-Ji8RWXTnFdoUP6PD .edge{stroke-width:3;}#mermaid-svg-Ji8RWXTnFdoUP6PD .section–1 rect,#mermaid-svg-Ji8RWXTnFdoUP6PD .section–1 path,#mermaid-svg-Ji8RWXTnFdoUP6PD .section–1 circle,#mermaid-svg-Ji8RWXTnFdoUP6PD .section–1 polygon,#mermaid-svg-Ji8RWXTnFdoUP6PD .section–1 path{fill:hsl(240, 100%, 76.2745098039%);}#mermaid-svg-Ji8RWXTnFdoUP6PD .section–1 text{fill:#ffffff;}#mermaid-svg-Ji8RWXTnFdoUP6PD .node-icon–1{font-size:40px;color:#ffffff;}#mermaid-svg-Ji8RWXTnFdoUP6PD .section-edge–1{stroke:hsl(240, 100%, 76.2745098039%);}#mermaid-svg-Ji8RWXTnFdoUP6PD .edge-depth–1{stroke-width:17;}#mermaid-svg-Ji8RWXTnFdoUP6PD .section–1 line{stroke:hsl(60, 100%, 86.2745098039%);stroke-width:3;}#mermaid-svg-Ji8RWXTnFdoUP6PD .disabled,#mermaid-svg-Ji8RWXTnFdoUP6PD .disabled circle,#mermaid-svg-Ji8RWXTnFdoUP6PD .disabled text{fill:lightgray;}#mermaid-svg-Ji8RWXTnFdoUP6PD .disabled text{fill:#efefef;}#mermaid-svg-Ji8RWXTnFdoUP6PD .section-0 rect,#mermaid-svg-Ji8RWXTnFdoUP6PD .section-0 path,#mermaid-svg-Ji8RWXTnFdoUP6PD .section-0 circle,#mermaid-svg-Ji8RWXTnFdoUP6PD .section-0 polygon,#mermaid-svg-Ji8RWXTnFdoUP6PD .section-0 path{fill:hsl(60, 100%, 73.5294117647%);}#mermaid-svg-Ji8RWXTnFdoUP6PD .section-0 text{fill:black;}#mermaid-svg-Ji8RWXTnFdoUP6PD .node-icon-0{font-size:40px;color:black;}#mermaid-svg-Ji8RWXTnFdoUP6PD .section-edge-0{stroke:hsl(60, 100%, 73.5294117647%);}#mermaid-svg-Ji8RWXTnFdoUP6PD .edge-depth-0{stroke-width:14;}#mermaid-svg-Ji8RWXTnFdoUP6PD .section-0 line{stroke:hsl(240, 100%, 83.5294117647%);stroke-width:3;}#mermaid-svg-Ji8RWXTnFdoUP6PD .disabled,#mermaid-svg-Ji8RWXTnFdoUP6PD .disabled circle,#mermaid-svg-Ji8RWXTnFdoUP6PD .disabled text{fill:lightgray;}#mermaid-svg-Ji8RWXTnFdoUP6PD .disabled text{fill:#efefef;}#mermaid-svg-Ji8RWXTnFdoUP6PD .section-1 rect,#mermaid-svg-Ji8RWXTnFdoUP6PD .section-1 path,#mermaid-svg-Ji8RWXTnFdoUP6PD .section-1 circle,#mermaid-svg-Ji8RWXTnFdoUP6PD .section-1 polygon,#mermaid-svg-Ji8RWXTnFdoUP6PD .section-1 path{fill:hsl(80, 100%, 76.2745098039%);}#mermaid-svg-Ji8RWXTnFdoUP6PD .section-1 text{fill:black;}#mermaid-svg-Ji8RWXTnFdoUP6PD .node-icon-1{font-size:40px;color:black;}#mermaid-svg-Ji8RWXTnFdoUP6PD .section-edge-1{stroke:hsl(80, 100%, 76.2745098039%);}#mermaid-svg-Ji8RWXTnFdoUP6PD .edge-depth-1{stroke-width:11;}#mermaid-svg-Ji8RWXTnFdoUP6PD .section-1 line{stroke:hsl(260, 100%, 86.2745098039%);stroke-width:3;}#mermaid-svg-Ji8RWXTnFdoUP6PD .disabled,#mermaid-svg-Ji8RWXTnFdoUP6PD .disabled circle,#mermaid-svg-Ji8RWXTnFdoUP6PD .disabled text{fill:lightgray;}#mermaid-svg-Ji8RWXTnFdoUP6PD .disabled text{fill:#efefef;}#mermaid-svg-Ji8RWXTnFdoUP6PD .section-2 rect,#mermaid-svg-Ji8RWXTnFdoUP6PD .section-2 path,#mermaid-svg-Ji8RWXTnFdoUP6PD .section-2 circle,#mermaid-svg-Ji8RWXTnFdoUP6PD .section-2 polygon,#mermaid-svg-Ji8RWXTnFdoUP6PD .section-2 path{fill:hsl(270, 100%, 76.2745098039%);}#mermaid-svg-Ji8RWXTnFdoUP6PD .section-2 text{fill:#ffffff;}#mermaid-svg-Ji8RWXTnFdoUP6PD .node-icon-2{font-size:40px;color:#ffffff;}#mermaid-svg-Ji8RWXTnFdoUP6PD .section-edge-2{stroke:hsl(270, 100%, 76.2745098039%);}#mermaid-svg-Ji8RWXTnFdoUP6PD .edge-depth-2{stroke-width:8;}#mermaid-svg-Ji8RWXTnFdoUP6PD .section-2 line{stroke:hsl(90, 100%, 86.2745098039%);stroke-width:3;}#mermaid-svg-Ji8RWXTnFdoUP6PD .disabled,#mermaid-svg-Ji8RWXTnFdoUP6PD .disabled circle,#mermaid-svg-Ji8RWXTnFdoUP6PD .disabled text{fill:lightgray;}#mermaid-svg-Ji8RWXTnFdoUP6PD .disabled text{fill:#efefef;}#mermaid-svg-Ji8RWXTnFdoUP6PD .section-3 rect,#mermaid-svg-Ji8RWXTnFdoUP6PD .section-3 path,#mermaid-svg-Ji8RWXTnFdoUP6PD .section-3 circle,#mermaid-svg-Ji8RWXTnFdoUP6PD .section-3 polygon,#mermaid-svg-Ji8RWXTnFdoUP6PD .section-3 path{fill:hsl(300, 100%, 76.2745098039%);}#mermaid-svg-Ji8RWXTnFdoUP6PD .section-3 text{fill:black;}#mermaid-svg-Ji8RWXTnFdoUP6PD .node-icon-3{font-size:40px;color:black;}#mermaid-svg-Ji8RWXTnFdoUP6PD .section-edge-3{stroke:hsl(300, 100%, 76.2745098039%);}#mermaid-svg-Ji8RWXTnFdoUP6PD .edge-depth-3{stroke-width:5;}#mermaid-svg-Ji8RWXTnFdoUP6PD .section-3 line{stroke:hsl(120, 100%, 86.2745098039%);stroke-width:3;}#mermaid-svg-Ji8RWXTnFdoUP6PD .disabled,#mermaid-svg-Ji8RWXTnFdoUP6PD .disabled circle,#mermaid-svg-Ji8RWXTnFdoUP6PD .disabled text{fill:lightgray;}#mermaid-svg-Ji8RWXTnFdoUP6PD .disabled text{fill:#efefef;}#mermaid-svg-Ji8RWXTnFdoUP6PD .section-4 rect,#mermaid-svg-Ji8RWXTnFdoUP6PD .section-4 path,#mermaid-svg-Ji8RWXTnFdoUP6PD .section-4 circle,#mermaid-svg-Ji8RWXTnFdoUP6PD .section-4 polygon,#mermaid-svg-Ji8RWXTnFdoUP6PD .section-4 path{fill:hsl(330, 100%, 76.2745098039%);}#mermaid-svg-Ji8RWXTnFdoUP6PD .section-4 text{fill:black;}#mermaid-svg-Ji8RWXTnFdoUP6PD .node-icon-4{font-size:40px;color:black;}#mermaid-svg-Ji8RWXTnFdoUP6PD .section-edge-4{stroke:hsl(330, 100%, 76.2745098039%);}#mermaid-svg-Ji8RWXTnFdoUP6PD .edge-depth-4{stroke-width:2;}#mermaid-svg-Ji8RWXTnFdoUP6PD .section-4 line{stroke:hsl(150, 100%, 86.2745098039%);stroke-width:3;}#mermaid-svg-Ji8RWXTnFdoUP6PD .disabled,#mermaid-svg-Ji8RWXTnFdoUP6PD .disabled circle,#mermaid-svg-Ji8RWXTnFdoUP6PD .disabled text{fill:lightgray;}#mermaid-svg-Ji8RWXTnFdoUP6PD .disabled text{fill:#efefef;}#mermaid-svg-Ji8RWXTnFdoUP6PD .section-5 rect,#mermaid-svg-Ji8RWXTnFdoUP6PD .section-5 path,#mermaid-svg-Ji8RWXTnFdoUP6PD .section-5 circle,#mermaid-svg-Ji8RWXTnFdoUP6PD .section-5 polygon,#mermaid-svg-Ji8RWXTnFdoUP6PD .section-5 path{fill:hsl(0, 100%, 76.2745098039%);}#mermaid-svg-Ji8RWXTnFdoUP6PD .section-5 text{fill:black;}#mermaid-svg-Ji8RWXTnFdoUP6PD .node-icon-5{font-size:40px;color:black;}#mermaid-svg-Ji8RWXTnFdoUP6PD .section-edge-5{stroke:hsl(0, 100%, 76.2745098039%);}#mermaid-svg-Ji8RWXTnFdoUP6PD .edge-depth-5{stroke-width:-1;}#mermaid-svg-Ji8RWXTnFdoUP6PD .section-5 line{stroke:hsl(180, 100%, 86.2745098039%);stroke-width:3;}#mermaid-svg-Ji8RWXTnFdoUP6PD .disabled,#mermaid-svg-Ji8RWXTnFdoUP6PD .disabled circle,#mermaid-svg-Ji8RWXTnFdoUP6PD .disabled text{fill:lightgray;}#mermaid-svg-Ji8RWXTnFdoUP6PD .disabled text{fill:#efefef;}#mermaid-svg-Ji8RWXTnFdoUP6PD .section-6 rect,#mermaid-svg-Ji8RWXTnFdoUP6PD .section-6 path,#mermaid-svg-Ji8RWXTnFdoUP6PD .section-6 circle,#mermaid-svg-Ji8RWXTnFdoUP6PD .section-6 polygon,#mermaid-svg-Ji8RWXTnFdoUP6PD .section-6 path{fill:hsl(30, 100%, 76.2745098039%);}#mermaid-svg-Ji8RWXTnFdoUP6PD .section-6 text{fill:black;}#mermaid-svg-Ji8RWXTnFdoUP6PD .node-icon-6{font-size:40px;color:black;}#mermaid-svg-Ji8RWXTnFdoUP6PD .section-edge-6{stroke:hsl(30, 100%, 76.2745098039%);}#mermaid-svg-Ji8RWXTnFdoUP6PD .edge-depth-6{stroke-width:-4;}#mermaid-svg-Ji8RWXTnFdoUP6PD .section-6 line{stroke:hsl(210, 100%, 86.2745098039%);stroke-width:3;}#mermaid-svg-Ji8RWXTnFdoUP6PD .disabled,#mermaid-svg-Ji8RWXTnFdoUP6PD .disabled circle,#mermaid-svg-Ji8RWXTnFdoUP6PD .disabled text{fill:lightgray;}#mermaid-svg-Ji8RWXTnFdoUP6PD .disabled text{fill:#efefef;}#mermaid-svg-Ji8RWXTnFdoUP6PD .section-7 rect,#mermaid-svg-Ji8RWXTnFdoUP6PD .section-7 path,#mermaid-svg-Ji8RWXTnFdoUP6PD .section-7 circle,#mermaid-svg-Ji8RWXTnFdoUP6PD .section-7 polygon,#mermaid-svg-Ji8RWXTnFdoUP6PD .section-7 path{fill:hsl(90, 100%, 76.2745098039%);}#mermaid-svg-Ji8RWXTnFdoUP6PD .section-7 text{fill:black;}#mermaid-svg-Ji8RWXTnFdoUP6PD .node-icon-7{font-size:40px;color:black;}#mermaid-svg-Ji8RWXTnFdoUP6PD .section-edge-7{stroke:hsl(90, 100%, 76.2745098039%);}#mermaid-svg-Ji8RWXTnFdoUP6PD .edge-depth-7{stroke-width:-7;}#mermaid-svg-Ji8RWXTnFdoUP6PD .section-7 line{stroke:hsl(270, 100%, 86.2745098039%);stroke-width:3;}#mermaid-svg-Ji8RWXTnFdoUP6PD .disabled,#mermaid-svg-Ji8RWXTnFdoUP6PD .disabled circle,#mermaid-svg-Ji8RWXTnFdoUP6PD .disabled text{fill:lightgray;}#mermaid-svg-Ji8RWXTnFdoUP6PD .disabled text{fill:#efefef;}#mermaid-svg-Ji8RWXTnFdoUP6PD .section-8 rect,#mermaid-svg-Ji8RWXTnFdoUP6PD .section-8 path,#mermaid-svg-Ji8RWXTnFdoUP6PD .section-8 circle,#mermaid-svg-Ji8RWXTnFdoUP6PD .section-8 polygon,#mermaid-svg-Ji8RWXTnFdoUP6PD .section-8 path{fill:hsl(150, 100%, 76.2745098039%);}#mermaid-svg-Ji8RWXTnFdoUP6PD .section-8 text{fill:black;}#mermaid-svg-Ji8RWXTnFdoUP6PD .node-icon-8{font-size:40px;color:black;}#mermaid-svg-Ji8RWXTnFdoUP6PD .section-edge-8{stroke:hsl(150, 100%, 76.2745098039%);}#mermaid-svg-Ji8RWXTnFdoUP6PD .edge-depth-8{stroke-width:-10;}#mermaid-svg-Ji8RWXTnFdoUP6PD .section-8 line{stroke:hsl(330, 100%, 86.2745098039%);stroke-width:3;}#mermaid-svg-Ji8RWXTnFdoUP6PD .disabled,#mermaid-svg-Ji8RWXTnFdoUP6PD .disabled circle,#mermaid-svg-Ji8RWXTnFdoUP6PD .disabled text{fill:lightgray;}#mermaid-svg-Ji8RWXTnFdoUP6PD .disabled text{fill:#efefef;}#mermaid-svg-Ji8RWXTnFdoUP6PD .section-9 rect,#mermaid-svg-Ji8RWXTnFdoUP6PD .section-9 path,#mermaid-svg-Ji8RWXTnFdoUP6PD .section-9 circle,#mermaid-svg-Ji8RWXTnFdoUP6PD .section-9 polygon,#mermaid-svg-Ji8RWXTnFdoUP6PD .section-9 path{fill:hsl(180, 100%, 76.2745098039%);}#mermaid-svg-Ji8RWXTnFdoUP6PD .section-9 text{fill:black;}#mermaid-svg-Ji8RWXTnFdoUP6PD .node-icon-9{font-size:40px;color:black;}#mermaid-svg-Ji8RWXTnFdoUP6PD .section-edge-9{stroke:hsl(180, 100%, 76.2745098039%);}#mermaid-svg-Ji8RWXTnFdoUP6PD .edge-depth-9{stroke-width:-13;}#mermaid-svg-Ji8RWXTnFdoUP6PD .section-9 line{stroke:hsl(0, 100%, 86.2745098039%);stroke-width:3;}#mermaid-svg-Ji8RWXTnFdoUP6PD .disabled,#mermaid-svg-Ji8RWXTnFdoUP6PD .disabled circle,#mermaid-svg-Ji8RWXTnFdoUP6PD .disabled text{fill:lightgray;}#mermaid-svg-Ji8RWXTnFdoUP6PD .disabled text{fill:#efefef;}#mermaid-svg-Ji8RWXTnFdoUP6PD .section-10 rect,#mermaid-svg-Ji8RWXTnFdoUP6PD .section-10 path,#mermaid-svg-Ji8RWXTnFdoUP6PD .section-10 circle,#mermaid-svg-Ji8RWXTnFdoUP6PD .section-10 polygon,#mermaid-svg-Ji8RWXTnFdoUP6PD .section-10 path{fill:hsl(210, 100%, 76.2745098039%);}#mermaid-svg-Ji8RWXTnFdoUP6PD .section-10 text{fill:black;}#mermaid-svg-Ji8RWXTnFdoUP6PD .node-icon-10{font-size:40px;color:black;}#mermaid-svg-Ji8RWXTnFdoUP6PD .section-edge-10{stroke:hsl(210, 100%, 76.2745098039%);}#mermaid-svg-Ji8RWXTnFdoUP6PD .edge-depth-10{stroke-width:-16;}#mermaid-svg-Ji8RWXTnFdoUP6PD .section-10 line{stroke:hsl(30, 100%, 86.2745098039%);stroke-width:3;}#mermaid-svg-Ji8RWXTnFdoUP6PD .disabled,#mermaid-svg-Ji8RWXTnFdoUP6PD .disabled circle,#mermaid-svg-Ji8RWXTnFdoUP6PD .disabled text{fill:lightgray;}#mermaid-svg-Ji8RWXTnFdoUP6PD .disabled text{fill:#efefef;}#mermaid-svg-Ji8RWXTnFdoUP6PD .section-root rect,#mermaid-svg-Ji8RWXTnFdoUP6PD .section-root path,#mermaid-svg-Ji8RWXTnFdoUP6PD .section-root circle,#mermaid-svg-Ji8RWXTnFdoUP6PD .section-root polygon{fill:hsl(240, 100%, 46.2745098039%);}#mermaid-svg-Ji8RWXTnFdoUP6PD .section-root text{fill:#ffffff;}#mermaid-svg-Ji8RWXTnFdoUP6PD .section-root span{color:#ffffff;}#mermaid-svg-Ji8RWXTnFdoUP6PD .section-2 span{color:#ffffff;}#mermaid-svg-Ji8RWXTnFdoUP6PD .icon-container{height:100%;display:flex;justify-content:center;align-items:center;}#mermaid-svg-Ji8RWXTnFdoUP6PD .edge{fill:none;}#mermaid-svg-Ji8RWXTnFdoUP6PD .mindmap-node-label{dy:1em;alignment-baseline:middle;text-anchor:middle;dominant-baseline:middle;text-align:center;}#mermaid-svg-Ji8RWXTnFdoUP6PD :root{–mermaid-font-family:\”trebuchet ms\”,verdana,arial,sans-serif;}
第10章 协作开发 9条建议
模块与包
第82条: 模块划分代码
第83条: 导入方式选择
第84条: 控制API可见性
第85条: 包组织模块
第86条: 命名空间包
配置与环境
第87条: 源文件编码
第88条: 依赖管理
第89条: 虚拟环境隔离
文档
第90条: 编写文档
第10章详细笔记:逐条精讲与源代码
本章是全书最终章,聚焦代码协作、项目组织与文档编写。掌握这些,你的代码将能顺畅地融入团队和社区,从“单打独斗”进阶为“专业协作”。
第82条:用模块划分代码,提供稳健的 API
核心:模块(.py文件)是 Python 代码组织的基本单元。好的模块应具有单一的、明确的主题,避免将所有功能塞进一个巨型文件中。顶层函数和类构成模块的 API。
# 假设文件: shop.py
"""购物车模块"""
class Cart:
def __init__(self):
self.items = []
def add(self, item):
self.items.append(item)
def total(self):
return sum(item.price for item in self.items)
def apply_discount(cart, percent):
for item in cart.items:
item.price *= (1 – percent / 100)
模块结构原则:
- 一个模块解决一个问题域
- 模块内用 import 引入依赖
- 使用 if __name__ == '__main__': 放置演示代码
- 避免循环导入
关键收获:清晰的模块边界让代码库易于导航和维护。
第83条:使用相对导入与绝对导入管理包内依赖
核心:在包内部引用兄弟模块时,可选择绝对导入(从包的根路径写起)或相对导入(使用 . 和 ..)。绝对导入更易读且不受模块位置变动影响,是推荐的默认选择。
# 包结构:
# mypkg/
# __init__.py
# models.py
# utils.py
# views/
# __init__.py
# main.py
# 在 mypkg/views/main.py 中:
# ✅ 绝对导入(推荐)
from mypkg.models import User
from mypkg import utils
# ✅ 相对导入(包内部,移动包时代码更少改动)
from ..models import User
from .. import utils
规则:
- 包内模块相互引用,用绝对导入最清晰
- 当包可能整体改名或移动时,相对导入方便
- 相对导入只能在包内使用(不能用于顶层脚本)
- from . import module 表示导入同级模块
关键收获:优先使用绝对导入;当包内结构很深且可能整体迁移时,考虑相对导入。
第84条:用 __all__ 控制模块 API 的可见性
核心:模块的 __all__ 列表定义了 from module import * 时导出的符号名称。这能清晰表达“公开接口”,同时避免内部实现污染调用方命名空间。
# helpers.py
__all__ = ['public_func', 'PublicClass']
def public_func():
return "I'm public"
def _internal_util(): # 约定为内部函数
return "Internal"
class PublicClass:
pass
class _InternalClass: # 约定为内部类
pass
调用方:
from helpers import *
print(public_func()) # 可用
print(PublicClass) # 可用
# print(_internal_util()) # NameError
关键收获:始终在大型模块中定义 __all__,作为给协作者的接口承诺。
第85条:用包组织模块,避免命名冲突
核心:当项目包含多个模块时,将它们组织到包(含 __init__.py 的目录)中,形成层级命名空间。包能封装相关功能,避免模块数过多导致的命名冲突。
# 项目结构示例
myapp/
__init__.py # 使 myapp 成为包
core/
__init__.py
engine.py
helpers.py
gui/
__init__.py
windows.py
dialogs.py
utils/
__init__.py
file_io.py
__init__.py 的职责:
- 可以空文件,仅标记目录为包
- 可以包含初始化代码
- 可以提前导入子模块,提升用户便利性
- 可以定义 __all__ 控制包级导出
关键收获:用包构建逻辑层次,就像文件系统中的文件夹。
第86条:用命名空间包创建无 __init__.py 的巨型包
核心:Python 3.3+ 支持命名空间包,由多个目录组成一个逻辑包,且不需要 __init__.py 文件。这允许不同的发行版各自提供同一个包的一部分,适合大型框架的插件系统。
# 目录结构(两个分开的路径)
# /path/to/mylibrary/framework/
# utils.py
# /other/path/mylibrary/framework/
# plugins.py
# 当两者都在 sys.path 中时,可以直接:
import mylibrary.framework.utils
import mylibrary.framework.plugins
使用场景:
- 大型框架(如 mpl_toolkits)
- 公司内部共享基础库,各团队添加子模块
- 安装时由多个包组合
注意:命名空间包没有 __file__ 属性。调试时可能略感困惑。
关键收获:命名空间包是把松散耦合的代码组织在一起的强力工具,但多数项目不需要。
第87条:用合适的编码和模块结构来适应团队
核心:源文件编码默认为 UTF-8(Python 3),无需手动声明。团队应统一编码规范(如 PEP 8)。此外,将易于修改的配置放在单独模块或文件中,而非硬编码。
# config.py
DB_HOST = "localhost"
DB_PORT = 5432
# main.py
from config import DB_HOST, DB_PORT
关键收获:编码和配置的规范化降低协作摩擦。
第88条:管理依赖,确保可重现的构建
核心:永远不要依赖系统全局的 Python 包。使用 requirements.txt 或 Pipfile/Pipfile.lock 锁定依赖版本,确保每位开发者与生产环境一致。
# 生成依赖文件
pip freeze > requirements.txt
# 安装依赖
pip install -r requirements.txt
新一代工具:pipenv 或 poetry 提供依赖解析和锁定,更为现代。
pipenv install requests
pipenv lock # 生成 Pipfile.lock
pipenv install –deploy # 严格按 lock 文件安装
关键收获:锁定依赖是职业开发者的底线,防止“在我机器上能跑”的噩梦。
第89条:用虚拟环境隔离项目环境
核心:每个项目都应有自己的虚拟环境,包含独立的 Python 解释器和第三方库。这避免了不同项目间的依赖冲突。
# 创建虚拟环境
python3 -m venv myproject_env
# 激活
source myproject_env/bin/activate # Linux/Mac
myproject_env\\Scripts\\activate # Windows
# 安装包(仅作用于该虚拟环境)
pip install pandas
使用 virtualenvwrapper 或 pipenv 可进一步简化环境管理。
关键收获:虚拟环境是 Python 项目的整洁桌面,隔离即自由。
第90条:编写文档字符串和模块级文档
核心:PEP 257 定义了文档字符串(docstring)的约定。每个模块、类、公共函数都应有说明用途的文档字符串。可使用 help() 或在 IDE 中显示,甚至通过 doctest 作为可运行的示例。
def add(a, b):
"""Return the sum of a and b.
>>> add(2, 3)
5
>>> add(-1, 1)
0
"""
return a + b
# 在模块开头编写模块级文档
"""mymodule – A set of math utilities.
This module provides basic arithmetic functions
for demonstration purposes.
"""
运行文档测试:
python -m doctest mymodule.py
关键收获:文档不是额外工作,而是代码的一部分。docstring 让代码自解释。
项目结构决策流程
#mermaid-svg-zlAme1Lr4s5pKBTB{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-zlAme1Lr4s5pKBTB .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-zlAme1Lr4s5pKBTB .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-zlAme1Lr4s5pKBTB .error-icon{fill:#552222;}#mermaid-svg-zlAme1Lr4s5pKBTB .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-zlAme1Lr4s5pKBTB .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-zlAme1Lr4s5pKBTB .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-zlAme1Lr4s5pKBTB .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-zlAme1Lr4s5pKBTB .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-zlAme1Lr4s5pKBTB .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-zlAme1Lr4s5pKBTB .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-zlAme1Lr4s5pKBTB .marker{fill:#333333;stroke:#333333;}#mermaid-svg-zlAme1Lr4s5pKBTB .marker.cross{stroke:#333333;}#mermaid-svg-zlAme1Lr4s5pKBTB svg{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-zlAme1Lr4s5pKBTB p{margin:0;}#mermaid-svg-zlAme1Lr4s5pKBTB .label{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;color:#333;}#mermaid-svg-zlAme1Lr4s5pKBTB .cluster-label text{fill:#333;}#mermaid-svg-zlAme1Lr4s5pKBTB .cluster-label span{color:#333;}#mermaid-svg-zlAme1Lr4s5pKBTB .cluster-label span p{background-color:transparent;}#mermaid-svg-zlAme1Lr4s5pKBTB .label text,#mermaid-svg-zlAme1Lr4s5pKBTB span{fill:#333;color:#333;}#mermaid-svg-zlAme1Lr4s5pKBTB .node rect,#mermaid-svg-zlAme1Lr4s5pKBTB .node circle,#mermaid-svg-zlAme1Lr4s5pKBTB .node ellipse,#mermaid-svg-zlAme1Lr4s5pKBTB .node polygon,#mermaid-svg-zlAme1Lr4s5pKBTB .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-zlAme1Lr4s5pKBTB .rough-node .label text,#mermaid-svg-zlAme1Lr4s5pKBTB .node .label text,#mermaid-svg-zlAme1Lr4s5pKBTB .image-shape .label,#mermaid-svg-zlAme1Lr4s5pKBTB .icon-shape .label{text-anchor:middle;}#mermaid-svg-zlAme1Lr4s5pKBTB .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-zlAme1Lr4s5pKBTB .rough-node .label,#mermaid-svg-zlAme1Lr4s5pKBTB .node .label,#mermaid-svg-zlAme1Lr4s5pKBTB .image-shape .label,#mermaid-svg-zlAme1Lr4s5pKBTB .icon-shape .label{text-align:center;}#mermaid-svg-zlAme1Lr4s5pKBTB .node.clickable{cursor:pointer;}#mermaid-svg-zlAme1Lr4s5pKBTB .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-zlAme1Lr4s5pKBTB .arrowheadPath{fill:#333333;}#mermaid-svg-zlAme1Lr4s5pKBTB .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-zlAme1Lr4s5pKBTB .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-zlAme1Lr4s5pKBTB .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-zlAme1Lr4s5pKBTB .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-zlAme1Lr4s5pKBTB .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-zlAme1Lr4s5pKBTB .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-zlAme1Lr4s5pKBTB .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-zlAme1Lr4s5pKBTB .cluster text{fill:#333;}#mermaid-svg-zlAme1Lr4s5pKBTB .cluster span{color:#333;}#mermaid-svg-zlAme1Lr4s5pKBTB div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-zlAme1Lr4s5pKBTB .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-zlAme1Lr4s5pKBTB rect.text{fill:none;stroke-width:0;}#mermaid-svg-zlAme1Lr4s5pKBTB .icon-shape,#mermaid-svg-zlAme1Lr4s5pKBTB .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-zlAme1Lr4s5pKBTB .icon-shape p,#mermaid-svg-zlAme1Lr4s5pKBTB .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-zlAme1Lr4s5pKBTB .icon-shape .label rect,#mermaid-svg-zlAme1Lr4s5pKBTB .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-zlAme1Lr4s5pKBTB .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-zlAme1Lr4s5pKBTB .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-zlAme1Lr4s5pKBTB :root{–mermaid-font-family:\”trebuchet ms\”,verdana,arial,sans-serif;}
单模块
多模块
是
否
开始一个新项目
创建虚拟环境
规划包结构
项目规模?
单文件 + 良好的文档字符串
使用包组织,含__init__.py
代码会被多个仓库共用?
考虑命名空间包
传统包 + 绝对导入
定义__all__管理API
编写文档字符串和模块文档
生成并锁定依赖 requirements.txt/Pipfile.lock
项目就绪,可协作开发
第10章总结:从独自编码到专业协作
学完本章,你已具备了将代码融入团队、长期维护和扩展的全部基本功。
全书完结 & 后续学习方向
恭喜!通读《Effective Python(第2版)》90条建议,你的 Python 内功已从“能写”跃升至“写得好、维护得住、协作得畅”。建议后续:
- 深入专项领域:Web 框架(Django/Flask)、数据科学(NumPy/Pandas)、异步编程高级应用
- 关注新版本:Python 年度更新会引入新语法和标准库,保持阅读 “What’s New” 文档
- 投入实战:参与开源项目,阅读优秀代码(如 requests、flask),实践书中原则
这本书将像字典一样陪伴你——常看常新。
本文为个人学习笔记,仅用于知识分享。如有错误,欢迎指正。
👍🏻 点赞 + 收藏 + 分享,让更多开发者看到这篇深度解析!❤️ 如果觉得有用,请给个赞支持一下作者!




