note
整理了一些 Python 开发中常见但容易踩坑的问题,希望对你有所帮助。
1. 可变默认参数(Mutable Default Arguments)
这是 Python 最经典的坑之一。
1 2 3 4 5 6 7 8 9
| def append_to(element, to=[]): to.append(element) return to
print(append_to(1))
print(append_to(2))
|
原因:默认参数在函数定义时就被评估,列表在每次调用中共享。
正确做法:
1 2 3 4 5
| def append_to(element, to=None): if to is None: to = [] to.append(element) return to
|
2. 字典迭代时修改(Dictionary Change Size During Iteration)
1 2 3 4 5 6
| d = {'a': 1, 'b': 2, 'c': 3}
for key in d: if key == 'a': del d[key]
|
正确做法:
1 2 3 4 5 6 7
| for key in list(d.keys()): if key == 'a': del d[key]
d = {k: v for k, v in d.items() if k != 'a'}
|
3. == 和 is 的区别
1 2 3 4 5 6 7 8 9 10
| a = [1, 2, 3] b = [1, 2, 3]
print(a == b) print(a is b)
c = "hello" d = "hello" print(c is d)
|
记住:
== 比较值
is 比较身份(内存地址)
- 比较 None 应该用
is None,而不是 == None
4. 循环变量作用域
1 2 3 4 5 6 7
|
result = [x for x in range(3)] print(x)
|
5. datetime 时的时区问题
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| from datetime import datetime
now = datetime.now() print(now)
from datetime import timezone, timedelta
now_utc = datetime.now(timezone.utc) print(now_utc)
tz = timezone(timedelta(hours=8)) now_beijing = now_utc.astimezone(tz) print(now_beijing)
|
6. requests 库的超时和重定向
1 2 3 4 5 6 7 8 9 10
| import requests
response = requests.get('https://example.com')
response = requests.get('https://example.com', timeout=5)
response = requests.get('https://example.com', timeout=5, allow_redirects=True)
|
7. 字符串格式化
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| print("Hello %s" % "World")
name = "World" print(f"Hello {name}")
print(f'Hello {name}') print(f"Hello {name}")
|
8. None 和空值的判断
1 2 3 4 5 6 7 8 9 10 11 12
| my_list = [] if my_list: print("Not empty")
if my_list is not None and len(my_list) > 0: print("Not empty")
if my_list: print("Not empty")
|
总结
Python 虽然简洁易用,但有些坑如果不注意真的会浪费很多调试时间。建议:
- 使用 linter(如 flake8、pylint)
- 使用 type hints
- 多看官方文档
- 遵循 PEP 8 规范
希望这些坑能帮你避雷!有问题欢迎评论区交流。
参考资料: