
Python 常被称作“可执行的伪代码”——语法简洁、上手极快这也是它成为最受欢迎入门语言的原因。但恰恰因为太容易上手很多新手在不知不觉中养成了隐蔽的坏习惯。这些习惯不会让程序立刻报错但会在你毫无防备的时候变成半夜十二点的报警电话。如果你想在 Python 这条路上走得更稳下面这五个常见错误越早避开越好。一、可变默认参数同一个坑绊倒过无数人这是一个让无数老手都中过招的“经典款”陷阱。看这段代码python复制下载def add_item(item, items[]): items.append(item) return items print(add_item(1)) # [1] print(add_item(2)) # [1, 2] —— 竟然返回了 [1, 2]很多新手会认为每次调用add_item时都会创建一个新的空列表但事实并非如此。Python 函数的默认参数在定义时被创建一次并在后续所有调用中复用同一个对象。也就是说那个空列表[]在函数定义时就被创建了之后每次调用都在同一个列表上操作。正确做法使用None作为默认值在函数内部初始化。python复制下载def add_item(item, itemsNone): if items is None: items [] items.append(item) return items这条规则适用于所有可变类型——列表、字典、集合统统要警惕。二、is与混淆值相等不等于身份相同这个错误的迷惑性极高因为大部分时候它不会出问题。python复制下载a [1, 2, 3] b [1, 2, 3] print(a b) # True —— 值相等 print(a is b) # False —— 但不是同一个对象比较的是值是否相等而is比较的是两个变量是否指向同一个对象即内存地址是否相同。更隐蔽的坑在这里python复制下载x 256 y 256 print(x is y) # True小整数缓存 x 257 y 257 print(x is y) # False超出缓存范围Python 对小整数-5 到 256做了缓存所以is恰好返回True容易让人误以为is和可以混用。一旦数字超出范围程序行为就变了——这种间歇性 Bug 最难排查。原则比较数值永远用只有判断None、True、False时才用is。三、循环中修改列表越改越乱越改越错新手常常写出这样的代码python复制下载numbers [1, 2, 3, 4, 5] for num in numbers: if num % 2 0: numbers.remove(num) print(numbers) # [1, 3, 5] —— 侥幸对了换个数据试试python复制下载numbers [1, 2, 3, 4] for num in numbers: if num % 2 0: numbers.remove(num) print(numbers) # [1, 3, 4] —— 4 没有被删除原因很简单删除元素后列表长度变了后续元素向前移动迭代器索引却继续递增导致跳过了本该检查的元素。正确做法遍历副本修改原列表。python复制下载numbers [1, 2, 3, 4] for num in numbers[:]: # 遍历副本 if num % 2 0: numbers.remove(num) print(numbers) # [1, 3]或者用更 Pythonic 的列表推导式python复制下载numbers [num for num in numbers if num % 2 ! 0]四、try/except吞掉所有异常比不处理更可怕有些新手写完try/except后为了让代码“看起来更健壮”会这样做python复制下载try: result risky_operation() except: pass # 安静地忽略所有错误这比不处理异常更可怕。这段代码把KeyboardInterrupt、MemoryError、SystemExit全吞了——连用户按 CtrlC 想终止程序都做不到。线上排查问题时异常被吞掉意味着你的日志一片空白根本不知道哪里出了问题。原则永远捕获具体的异常类型永远记录错误信息。python复制下载try: result risky_operation() except ValueError as e: logger.error(f数据格式错误: {e}) raise except ConnectionError as e: logger.error(f网络连接失败: {e}) return fallback_result要么记录、要么重新抛出、要么妥善处理——唯独不能悄无声息地吞掉。五、import的幽灵变量让你失去对代码的掌控from module import是 Python 手册里明确不推荐的用法因为它会把模块里所有名字一股脑塞进当前命名空间。python复制下载from math import from statistics import # 问题来了sqrt 和 mean 来自哪个模块更隐蔽的问题是如果两个模块有同名函数后导入的会覆盖先导入的而且没有任何警告。python复制下载from module_a import # 定义了 func from module_b import # 也定义了 func悄悄覆盖了 module_a 的 funcIDE 无法对import导入的函数做自动补全和跳转代码的可维护性大打折扣。大型项目里这种写法会让后续维护的人包括未来的你自己抓狂。原则永远明确导入你需要的内容。python复制下载from math import sqrt, ceil from statistics import mean如果模块名太长用别名python复制下载import numpy as np import pandas as pd这样既清晰又简洁。写在最后以上五个错误几乎每个 Python 开发者都踩过。它们不会让程序立即崩溃但会在某个夜深人静的线上故障时刻让你追悔莫及。编程能力的提升不在于你写出了多少行代码而在于你避开了多少坑。可变默认参数用None替代比较数值永远用修改列表时遍历副本捕获异常时明确类型导入时指名道姓——养成这几个习惯你的 Python 代码质量会上一个大台阶。少走弯路就是最快的路。