
在 Python 开发中代码的可读性往往比单纯的“能跑”更重要。正如 Python 之禅The Zen of Python所言“Readability counts可读性很重要”。一套严谨、统一的命名规范不仅能降低团队的沟通成本还能让代码在数月甚至数年后依然易于维护。以下是一份详尽的 Python 命名规范技术指南涵盖了从基础变量到高级架构的方方面面并辅以代码示例。一、 核心原则PEP 8 与 Pythonic 风格Python 的官方风格指南PEP 8是命名的基石。其核心思想是名称应当具有描述性且在不同作用域内保持一致。避免无意义的单字母除了循环中的i, j, k或数学公式中的x, y尽量不要使用a, b, c。避免误导性名称不要使用hp代表hypotenuse除非上下文极度明确。长度适中变量名不宜过长但必须准确。data不如user_profileuser_profile不如active_user_profile视上下文而定。二、 命名风格速查表Python 对不同代码元素有明确的风格约定切勿混用元素类型命名风格示例备注变量 / 函数 / 方法snake_case(小写下划线)user_name,get_total()最基础的 Python 风格类 / 异常PascalCase(大驼峰)UserProfile,ValueError单词首字母大写无下划线常量UPPER_SNAKE_CASEMAX_RETRY_COUNT,PI全大写单词间下划线模块 / 文件snake_casedata_processor.py尽量简短避免连字符类型变量PascalCaseUserId,ResponseDataTypeVar 或 TypeAlias私有成员_leading_underscore_internal_cache约定俗成的“请勿外部访问”强私有成员__double_leading__secret_key触发名称修饰 (Name Mangling)魔术方法__dunder____init__,__str__系统保留禁止自定义三、 变量与函数命名语义化是关键1. 布尔值命名布尔变量应像问句或状态描述通常以is_,has_,can_,should_开头。# ❌ 错误示范flagTruecheckFalsevalidTrue# 什么是 valid# ✅ 正确示范is_authenticatedTruehas_active_subscriptionFalseis_email_verifiedTruecan_edit_documentFalse2. 集合与容器使用复数名词表示集合使用单数名词表示元素。# ❌ 错误示范user_list[]data_dict{}# ✅ 正确示范users[]user_profiles{}active_sessionsset()3. 函数命名动词 名词函数名应描述“它做什么”而不是“它是什么”。# ❌ 错误示范defuser():...# 这是函数还是类defprocess():...# 处理什么defget():...# 获取什么# ✅ 正确示范defget_user_by_id(user_id:int)-User:...defcalculate_monthly_revenue(transactions:list)-float:...defsend_welcome_email(user:User)-None:...defis_password_strong(password:str)-bool:...四、 类与面向对象命名1. 类名即名词类是对象的蓝图名称应为名词或名词短语。# ❌ 错误示范classRun:...classData:...classManageUser:...# 动词开头通常是函数# ✅ 正确示范classTaskRunner:...classUserDataset:...classUserManager:...# 如果必须用动词表示“管理器”角色2. 属性与方法公开属性snake_case如user.name。受保护属性_snake_case表示子类可访问但外部不应直接修改。私有属性__snake_casePython 会将其转换为_ClassName__snake_case用于避免子类命名冲突。classBankAccount:def__init__(self,owner:str,balance:float):self.ownerowner# 公开self._balancebalance# 受保护建议通过方法访问self.__pin_code1234# 私有名称修饰propertydefbalance(self)-float:通过 Property 暴露受保护属性returnself._balancedefdeposit(self,amount:float):ifamount0:raiseValueError(Amount must be positive)self._balanceamount五、 模块与包结构命名全小写utils.py,database.py。避免标准库冲突不要命名为email.py,json.py,random.py这会导致import时加载你自己的文件而非标准库。包名简短myproject.core,myproject.utils。__init__.py用于标记目录为包也可用于简化导入路径但现代 Python 建议显式导入。my_project/ ├── __init__.py ├── main.py ├── models/ │ ├── __init__.py │ ├── user.py # class User │ └── order.py # class Order └── services/ ├── __init__.py └── payment_service.py # class PaymentService六、 高级命名技巧与陷阱1. 避免使用保留字不要使用list,dict,id,type,input作为变量名这会覆盖内置函数。# ❌ 危险list[1,2,3]print(list(10))# TypeError: list object is not callable# ✅ 安全numbers[1,2,3]# 或者加后缀id_100class_A2. 类型提示中的命名类型别名使用PascalCase泛型变量使用单个大写字母或描述性 PascalCase。fromtypingimportTypeVar,Protocol# 类型别名UserIdintJsonResponsedict[str,Any]# 泛型TTypeVar(T)KTTypeVar(KT)# Key TypeVTTypeVar(VT)# Value TypeclassRepository(Protocol[T]):defget(self,item_id:int)-T:...3. 上下文管理器与生成器# 上下文管理器名词或动词ingwithopen(file.txt)asf:...withdatabase.transaction()astxn:...# 生成器通常用动词复数或 yield 相关defread_lines(filepath:str):withopen(filepath)asf:forlineinf:yieldline.strip()七、 综合实战代码示例以下是一个结合了上述所有规范的完整示例 user_service.py 处理用户注册与验证的核心服务模块。 importloggingfromtypingimportOptionalfromdatetimeimportdatetime# 常量全大写MAX_LOGIN_ATTEMPTS5SESSION_TIMEOUT_SECONDS3600loggerlogging.getLogger(__name__)classAuthenticationError(Exception):自定义异常PascalCasepassclassUserService: 用户服务类。 遵循 PascalCase 命名职责单一。 def__init__(self,db_connector,cache_client):# 依赖注入使用描述性名称self._dbdb_connector self._cachecache_client self._active_sessions:dict[int,datetime]{}defregister_user(self,username:str,email:str,password:str)-int: 注册新用户并返回 user_id。 动词 名词结构。 ifself._is_email_taken(email):raiseValueError(fEmail{email}already exists)# 内部方法下划线前缀hashed_pwself._hash_password(password)user_idself._db.insert_user(usernameusername,emailemail,password_hashhashed_pw)logger.info(fUser registered:{username}(ID:{user_id}))returnuser_iddeflogin(self,email:str,password:str)-str: 验证凭证并返回 session_token。 userself._db.get_user_by_email(email)ifnotuserornotself._verify_password(password,user.password_hash):self._increment_failed_attempts(email)raiseAuthenticationError(Invalid credentials)tokenself._generate_session_token(user.id)self._active_sessions[user.id]datetime.now()returntoken# --- 私有/受保护方法 ---def_is_email_taken(self,email:str)-bool:检查邮箱是否已被占用。returnself._db.query(SELECT 1 FROM users WHERE email %s,email)isnotNonestaticmethoddef_hash_password(plain_text:str)-str:密码哈希处理。# 实际应使用 bcrypt/argon2importhashlibreturnhashlib.sha256(plain_text.encode()).hexdigest()def_verify_password(self,plain_text:str,hashed:str)-bool:returnself._hash_password(plain_text)hasheddef_generate_session_token(self,user_id:int)-str:returnftok_{user_id}_{int(datetime.now().timestamp())}def_increment_failed_attempts(self,email:str)-None:keyffail_count:{email}currentself._cache.get(key,0)self._cache.set(key,current1,exSESSION_TIMEOUT_SECONDS)八、 自动化与团队执行规范不能仅靠“人治”必须依靠工具Linter: 配置ruff或flake8开启N(pep8-naming) 规则。# pyproject.toml [tool.ruff.lint] select [E, F, N, I] # N pep8-namingFormatter: 使用black或ruff format统一代码格式虽然主要管缩进但也辅助命名间距。Type Checker: 使用mypy或pyright强制类型命名规范。Code Review: 在 PR 中重点检查命名是否准确而不是纠结于空格。总结Python 命名规范的本质是降低认知负荷。看到snake_case你知道这是数据或行为。看到PascalCase你知道这是结构或蓝图。看到_前缀你知道这是内部细节。看到UPPER_CASE你知道这是不可变的配置。好的命名是代码的注释而最好的命名让注释变得多余。在敲下每一个变量名时多花 3 秒钟思考“三个月后的我看到这个名字能立刻明白它的含义吗” 如果答案是否定的请重命名。