9 个习惯表明你不是专业的 Python 开发者
代码是程序员最好的名片。如果你希望成为一名专业的 Python 开发人员,除了掌握语法之外,更重要的是养成良好的编码习惯。本文将纠正你多年以来从其他语言坚持而来的坏习惯,帮助你写出更 Pythonic、更健壮的代码。
本文探讨了 Python 开发中的九个常见误区,涵盖字符串拼接、可变默认参数、推导式使用、相等性与同一性判断、元组解包、索引计数器、日志记录、导入方式及编码规范。通过对比错误示例与最佳实践,旨在帮助开发者提升代码可读性、维护性及专业性,遵循 Pythonic 风格。文章详细解释了每个问题的原理及修复方案,强调使用 f-string、logging 模块、enumerate 等特性,并建议遵循 PEP8 规范以避免命名冲突和保持代码整洁。

代码是程序员最好的名片。如果你希望成为一名专业的 Python 开发人员,除了掌握语法之外,更重要的是养成良好的编码习惯。本文将纠正你多年以来从其他语言坚持而来的坏习惯,帮助你写出更 Pythonic、更健壮的代码。
大多数时候,Python 初学者在组合两个或多个字符串时会使用 + 号。虽然这种方式可行,但在处理复杂格式时效率低且易出错。
错误示例:
name = "Ridwan"
age = "22"
print("My Name is " + name + " and I am " + age + " years old")
最佳实践: 应使用 f-string(格式化字符串字面量),这是 Python 3.6+ 引入的特性。它使代码可读性更强、简洁且不易出错。
print(f"My Name is {name} and I am {age} years old")
f-string 允许直接在字符串中嵌入表达式,性能也优于传统的 % 格式化或 .format() 方法。
在 Python 中,默认参数是在函数定义时计算的,而不是每次调用时。如果将可变对象(如列表、字典)作为默认参数,它们会在所有函数调用之间共享状态,导致难以追踪的 bug。
错误示例:
def append(n, l=[]):
l.append(n)
return l
l1 = append(0)
print(l1) # [0]
l2 = append(1)
print(l2) # [0, 1] - 注意这里保留了第一次调用的结果
解决方案:
将默认值设为 None,并在函数内部初始化可变对象。
def append(n, l=None):
if l is None:
l = []
l.append(n)
return l
l1 = append(0)
l2 = append(1)
print(l1) # [0]
print(l2) # [1]
这样确保了每次调用函数时,如果没有传入列表,都会创建一个新的空列表。
Python 推导式(Comprehensions)提供了一种构建序列的简洁方式。Python 支持四种类型的推导式:列表、集合、字典和生成器。
传统写法:
numbers = {}
for i in range(10):
numbers[i] = i / 2
推导式写法:
numbers = {i: i / 2 for i in range(10)}
推导式不仅代码更短,而且通常比等效的 for 循环执行速度更快,因为它们是在 C 层面优化的。建议在使用列表生成器时优先考虑此方式。
在 Python 中,检查变量是否相同需要理解 == 和 is 的区别。
== 比较的是值(Equality)。is 比较的是内存地址(Identity)。示例:
a = [1, 2, 3]
b = [1, 2, 3]
print(a == b) # True (值相同)
print(a is b) # False (内存地址不同)
c = [1, 2, 3]
d = c
print(c == d) # True
print(c is d) # True (指向同一个对象)
在判断单例模式对象、None 或布尔值时,应优先使用 is;在比较数值、字符串内容或数据结构内容时,应使用 ==。
当你在 Python 中创建一个元组时,可以通过索引访问元素,但更优雅的方式是使用元组解包(Tuple Unpacking)。
传统方式:
a_tuple = 1, 2, 3
x = a_tuple[0]
y = a_tuple[1]
z = a_tuple[2]
推荐方式:
x, y, z = a_tuple
元组解包不仅减少了代码行数,还提高了可读性,特别是在交换变量值时非常有用。
在其他编程语言中,遍历列表时常需手动维护索引计数器。在 Python 中,应使用内置的 enumerate 函数。
不推荐:
a_list = [1, 2, 3, 4, 5]
index = 0
for elem in a_list:
print(index, elem)
index += 1
推荐:
for index, elem in enumerate(a_list):
print(index, elem)
enumerate 返回一个迭代器,包含索引和对应的元素,符合 Python 风格(Pythonic),避免了手动管理计数器的繁琐和潜在错误。
在生产环境中,使用 print 语句调试或输出信息是不专业的做法。print 无法控制级别,也无法灵活地重定向到文件或其他处理器。
不推荐:
print('This is a warning message')
print('This is an error message')
推荐:
import logging
logging.basicConfig(level=logging.INFO)
logging.warning('This is a warning message')
logging.error('This is an error message')
logging.critical('This is a critical message')
日志记录模块(logging)提供了丰富的功能,包括日志级别(DEBUG, INFO, WARNING, ERROR, CRITICAL)、格式化器、处理器(控制台、文件、网络等),便于在大型项目中管理和排查问题。
使用 from module import * 会破坏命名空间,将该模块中的所有公共名称导入当前作用域。这可能导致与现有变量名冲突,并增加代码的可读性和维护难度。
不推荐:
from math import *
推荐:
import math
# 或者
from math import sqrt, pi
显式导入有助于明确依赖来源,减少命名污染,方便 IDE 进行静态分析和自动补全。
PEP8 是 Python 官方的编码风格指南。遵循它能让你的代码更易读、更易被他人理解。
不推荐:
def function():
x=[1,2,3]
y= [2,3,5]
推荐:
def function():
x = [1, 2, 3]
y = [2, 3, 5]
主要差异在于空格的使用、运算符两侧的空格以及缩进的一致性。建议使用工具如 black 或 flake8 来自动检查和格式化代码。
成为专业 Python 开发者的过程就是不断修正这些细微习惯的过程。通过遵循上述最佳实践,你可以显著提升代码质量、可维护性以及团队协作效率。记住,好的代码不仅是能运行的代码,更是易于理解和扩展的代码。

微信公众号「极客日志」,在微信中扫描左侧二维码关注。展示文案:极客日志 zeeklog
解析常见 curl 参数并生成 fetch、axios、PHP curl 或 Python requests 示例代码。 在线工具,curl 转代码在线工具,online
将字符串编码和解码为其 Base64 格式表示形式即可。 在线工具,Base64 字符串编码/解码在线工具,online
将字符串、文件或图像转换为其 Base64 表示形式。 在线工具,Base64 文件转换器在线工具,online
将 Markdown(GFM)转为 HTML 片段,浏览器内 marked 解析;与 HTML转Markdown 互为补充。 在线工具,Markdown转HTML在线工具,online
将 HTML 片段转为 GitHub Flavored Markdown,支持标题、列表、链接、代码块与表格等;浏览器内处理,可链接预填。 在线工具,HTML转Markdown在线工具,online
通过删除不必要的空白来缩小和压缩JSON。 在线工具,JSON 压缩在线工具,online