当前位置: 首页 > news >正文

Python基础:Python命名规范与命名习惯全掌握

Python基础:Python命名规范与命名习惯全掌握

一、开篇:名字很重要

编程中有两句经典名言:

  • “程序里最难的两件事:缓存失效和命名。”
  • “代码是写给人看的,顺便给机器运行。”

这两句话都指向同一个核心问题:给变量、函数、类起好名字是编程中最重要也最难的事之一

📝 一个好的命名,能让代码像阅读文章一样流畅;一个糟糕的命名,能让最简单的逻辑变得令人费解。这篇文章,我会把Python中的命名规范和实战技巧完整地讲清楚。

二、PEP 8命名规范全表

PEP 8(Python Enhancement Proposal 8)是Python官方代码风格指南。下面是其中关于命名的完整规范:

命名对象规范示例
变量名snake_casestudent_name,total_count
函数名snake_casecalculate_average(),get_user()
类名PascalCaseStudentRecord,FileManager
常量名UPPER_SNAKE_CASEMAX_SIZE,DEFAULT_PORT
模块名lower_snakedata_utils.py,user_models.py
包名lowercasemypackage,utils
异常类名PascalCase + ErrorValueError,ConnectionError
私有属性/方法_leading_underscore_internal_method(),_cache
"魔术"方法double_underscore__init__(),__str__(),__len__()
名称混淆__leading_double__private_attr(触发名称改写)

2.1 各种命名风格的名称

snake_case='全小写,单词用下划线连接'# 变量、函数PascalCase='每个单词首字母大写'# 类名camelCase='第一个单词小写,后面首字母大写'# Python不推荐UPPER_SNAKE_CASE='全大写,单词用下划线连接'# 常量kebab-case='全小写,单词用连字符连接'# Python不支持,CSS/HTML用

三、变量命名实战

3.1 使用描述性的名字

好的变量名应该能回答"这个变量存的是什么":

# ✅ 好命名——自解释student_count=42average_score=85.5is_user_logged_in=Truedefault_page_size=20max_retry_attempts=3upload_directory_path='/data/uploads'error_message_template='错误:{code} - {message}'# ❌ 差命名——需要猜测或查看上下文n=42# n是什么的数量?avg=85.5# 什么的平均值?flag=True# 什么标志?ps=20# 什么的大小?r=3# 重试次数?path='/data'# 什么路径?msg='错误...'# 什么消息?

3.2 布尔变量的命名

布尔变量(True/False)有几种推荐的命名方式:

# 用 is_ 前缀is_active=Trueis_admin=Falseis_deleted=False# 用 has_ 前缀has_permission=Truehas_children=Falsehas_errors=True# 用 should_ / can_ / will_ 等情态动词should_update=Truecan_delete=Falsewill_expire=True# 直接用形容词visible=Trueenabled=Falseready=Trueempty=False

💡 布尔变量命名技巧:读出来能构成一个自然的"Yes/No"问题。比如is_active读作"是活跃的吗?"——回答是True或False。如果变量名叫active,效果也一样。

3.3 数字变量的命名

# 计数类student_count=42# 学生数量retry_count=3# 重试次数# 度量类file_size_bytes=1024# 文件大小(字节)timeout_seconds=30# 超时时间(秒)distance_meters=100# 距离(米)# 索引类current_index=0# 当前索引start_position=5# 起始位置page_number=1# 页码# 比率类success_rate=0.95# 成功率discount_percent=0.15# 折扣百分比

3.4 集合变量的命名

# 列表/集合——用复数students=['小明','小红','小刚']scores=[85,92,78]active_users=set()# 字典——用描述性的名词student_scores={'小明':85,'小红':92}user_profiles={}# 用户资料config_settings={}# 配置设置# 用后缀提示类型(在类型不明确时)name_list=['小明','小红']score_dict={'math':95,'english':88}user_set=set()item_tuple=(1,2,3)

⚠️ 注意:在变量名中加类型后缀(如_list_dict)是有争议的。有些人认为这是代码坏味道——如果你的变量名需要加上类型后缀才能说清楚它是什么,说明你需要更好的名字,或者考虑使用类型注解。我个人建议:优先使用不带后缀的描述性名称,只有在确实容易混淆时才加后缀。

四、函数命名实战

4.1 函数名用动词开头

函数做事情,所以名字应该以动词开头:

# ✅ 好的函数名——动词开头,一看就知道做什么defcalculate_average(numbers):passdefget_user_by_id(user_id):passdefsave_data_to_file(data,filepath):passdefsend_email_notification(recipient,message):passdefvalidate_user_input(input_string):passdefparse_json_response(response_text):passdefconvert_celsius_to_fahrenheit(celsius):pass# ❌ 不好的函数名defaverage(numbers):# 名词,不知道是计算还是获取passdefuser(user_id):# 太模糊passdefdata_file(data,path):# 不知道要做什么pass

4.2 常用的函数动词前缀

前缀含义示例
get_获取/读取数据get_user(),get_config()
set_设置数据set_name(),set_timeout()
create_创建新对象create_order(),create_file()
delete_删除对象delete_user(),delete_record()
update_更新数据update_profile(),update_status()
calculate_计算结果calculate_total(),calculate_tax()
validate_验证数据validate_email(),validate_input()
parse_解析数据parse_json(),parse_url()
convert_转换格式convert_to_json(),convert_units()
check_检查状态check_connection(),check_permission()
find_查找数据find_user(),find_duplicates()
sort_排序sort_by_date(),sort_descending()
filter_筛选数据filter_by_status(),filter_active()
handle_处理事件handle_error(),handle_click()
process_处理数据process_payment(),process_file()
build_构造/构建build_url(),build_response()

4.3 返回布尔值的函数

# ✅ 用 is_ / has_ / can_ 前缀defis_valid_email(email):passdefhas_required_fields(data):passdefcan_user_access(user,resource):pass# 读起来像自然的Yes/No问题ifis_valid_email(user_input):register_user(user_input)

五、类命名实战

5.1 类名用名词

类代表"东西/概念",用PascalCase命名:

# ✅ 好类名——名词,PascalCaseclassStudent:"""学生"""passclassEmailSender:"""邮件发送器"""passclassDatabaseConnection:"""数据库连接"""passclassOrderManager:"""订单管理器"""passclassUserProfile:"""用户资料"""pass# ❌ 不好的类名classDoStudent:# 不要动词开头classemail_sender:# 不要蛇形命名classuser_profile:# 不要蛇形命名classA:# 太短了classProcessDataClass:# 不要后缀Class

5.2 异常类命名

# 异常类以Error结尾classValidationError(Exception):"""验证错误"""passclassDatabaseConnectionError(Exception):"""数据库连接错误"""passclassAuthenticationFailedError(Exception):"""认证失败错误"""passclassInvalidInputError(ValueError):"""无效输入错误"""pass

六、常量和配置命名

# 常量——全大写+下划线PI=3.141592653589793MAX_CONNECTIONS=100DEFAULT_TIMEOUT_SECONDS=30DATABASE_URL='mysql://localhost:3306/mydb'ALLOWED_EXTENSIONS={'.jpg','.png','.gif'}# 配置类——用类来组织相关常量classConfig:"""应用程序配置"""DEBUG=FalseSECRET_KEY='your-secret-key-here'DATABASE_URI='sqlite:///app.db'MAX_CONTENT_LENGTH=16*1024*1024# 16MBSESSION_COOKIE_NAME='session_id'# 使用枚举来定义一组相关常量fromenumimportEnumclassOrderStatus(Enum):PENDING='pending'CONFIRMED='confirmed'SHIPPED='shipped'DELIVERED='delivered'CANCELLED='cancelled'

七、下划线的五种含义

下划线在Python命名中有特殊的含义。理解这些约定对于阅读和编写Python代码很重要。

7.1 单前导下划线:_name

表示"受保护的/内部使用的"属性或方法。这是一个约定,不是强制规则。

classUser:def__init__(self,name):self.name=name self._password_hash=self._hash_password('default')def_hash_password(self,password):"""内部方法——不希望在类外部被调用"""importhashlibreturnhashlib.sha256(password.encode()).hexdigest()defcheck_password(self,password):"""公开方法——对外接口"""returnself._hash_password(password)==self._password_hash

从类外部仍然可以访问_password_hash_hash_password(),但按照约定,你不应该这么做。

user=User('小明')# 技术上可以访问,但约定上"不应该"print(user._password_hash)# 能工作,但不推荐

7.2 单后置下划线:name_

当变量名和Python关键字冲突时,在后面加一个下划线:

# class是关键字,用作变量名时加后缀class_='Computer Science 101'type_='选修'id_=12345list_=[1,2,3]

7.3 双前导下划线:__name

触发Python的名称改写(name mangling)机制,用于避免子类中的命名冲突:

classParent:def__init__(self):self.public='公开属性'self._protected='受保护属性'self.__private='私有属性(名称改写)'classChild(Parent):def__init__(self):super().__init__()# 可以访问print(self.public)# 公开属性print(self._protected)# 受保护属性# print(self.__private) # AttributeError! 找不到# 实际上Python把它改名了,可以通过改名后的名字访问# (但不要这么做!)print(self._Parent__private)# 输出:私有属性(名称改写)c=Child()

Python把__private改写为_Parent__private(前面加了类名),这样父类和子类的同名双下划线属性就不会冲突。但这种用法在Python社区中并不普遍,大多数情况下单下划线_protected就足够了。

7.4 双前后下划线:name

这是Python内置的"魔术方法"(magic methods)。永远不要自己创造这样的名字,只使用Python定义好的:

classMyClass:def__init__(self):# 构造方法passdef__str__(self):# 字符串表示return'MyClass实例'def__len__(self):# len()调用return0def__add__(self,other):# + 运算符returnself

7.5 单独的下划线:_

有三种用法:

# 用法一:表示"不会用到的变量"for_inrange(5):# 不需要用到循环变量print('循环中')# 用法二:交互式环境中表示"上一次表达式的结果">>>1+23>>>_*26# 用法三:占位符name,_,city=('小明',25,'北京')# 年龄25我们不需要print(name,city)

八、避免的命名坏习惯

8.1 拼音命名

# ❌ 不要用拼音xuesheng_mingzi='小明'shuliang=100chaxun_yonghu=True# ✅ 用英文student_name='小明'count=100query_user=True

如果你觉得英文表达不出来,宁可先用中文拼音(加注释),然后查词典找到正确的英文表达。不过说实话,很多国内项目中文拼音也照样用,主要看团队习惯。

8.2 缩写不当

# ❌ 过度缩写,难以理解stu_nm='小明'cal_avg_scr=85.5upd_usr_sts=True# ✅ 完整拼写student_name='小明'calculate_average_score=85.5update_user_status=True# 某些广为人知的缩写可以接受# OK——这些缩写大家都能理解num=100# numbermsg='hello'# messagecfg=load_config()# configdb=connect_db()# databaseidx=0# indextmp='/tmp'# temporary

8.3 命名中包含类型信息(过时的做法)

# ❌ 匈牙利命名法——Python不推荐strName='小明'# str前缀表示字符串iAge=25# i前缀表示整数lstStudents=[]# lst前缀表示列表bFlag=True# b前缀表示布尔值# ✅ Python的推荐做法name='小明'age=25students=[]flag=True# 如果确实需要标注类型,用类型注解name:str='小明'age:int=25students:list[str]=[]flag:bool=True

8.4 容易混淆的字符

# 避免容易混淆的命名# ❌ 容易搞混的:字母O和数字0,字母l和数字1O0='注意看区别'# 字母O+数字0l1='注意看区别'# 小写L+数字1

九、命名检查工具

9.1 pylint

pipinstallpylint# 检查一个文件的命名规范pylint my_script.py

pylint会检查变量名是否符合命名规范,并给出建议。

9.2 flake8 + pep8-naming

pipinstallflake8 pep8-naming# 检查命名规范flake8 my_script.py

9.3 IDE内置检查

PyCharm和VS Code + Pylance都会在你编写代码时实时检查命名规范,不符合PEP 8的命名会有下划线提示。

十、一个完整的命名示例

下面用一个真实的例子,展示好的命名如何让代码"会说话":

fromdataclassesimportdataclassfromtypingimportOptional# 类型别名StudentId=strScore=float@dataclassclassStudent:"""学生信息"""student_id:StudentId name:strage:intscores:list[Score]classGradeAnalyzer:"""成绩分析器——分析学生成绩并生成报告"""PASS_SCORE=60.0EXCELLENT_SCORE=90.0def__init__(self,students:list[Student]):self.students=studentsdefcalculate_average_score(self)->float:"""计算所有学生的平均成绩"""total_score=0.0total_count=0forstudentinself.students:ifstudent.scores:total_score+=sum(student.scores)total_count+=len(student.scores)iftotal_count==0:return0.0returntotal_score/total_countdeffind_top_students(self,top_count:int=3)->list[Student]:"""找出成绩最好的N个学生"""returnsorted(self.students,key=lambdas:sum(s.scores)/len(s.scores)ifs.scoreselse0,reverse=True)[:top_count]defget_pass_rate(self)->float:"""计算及格率"""passing_students=[sforsinself.studentsifs.scoresand(sum(s.scores)/len(s.scores))>=self.PASS_SCORE]ifnotself.students:return0.0returnlen(passing_students)/len(self.students)*100defgenerate_grade_report(self)->str:"""生成成绩分析报告"""report_lines=[]report_lines.append('='*50)report_lines.append('学生成绩分析报告')report_lines.append('='*50)report_lines.append(f'学生总数:{len(self.students)}人')report_lines.append(f'平均成绩:{self.calculate_average_score():.2f}分')report_lines.append(f'及格率:{self.get_pass_rate():.1f}%')report_lines.append('-'*50)report_lines.append('Top 3 学生:')forrank,studentinenumerate(self.find_top_students(3),1):avg=sum(student.scores)/len(student.scores)ifstudent.scoreselse0report_lines.append(f'{rank}.{student.name}-{avg:.2f}分')report_lines.append('='*50)return'\n'.join(report_lines)# 使用示例if__name__=='__main__':students=[Student('001','小明',20,[85.0,92.0,78.0]),Student('002','小红',21,[95.0,88.0,91.0]),Student('003','小刚',19,[55.0,60.0,58.0]),Student('004','小丽',22,[72.0,68.0,75.0]),Student('005','小华',20,[98.0,96.0,94.0]),]analyzer=GradeAnalyzer(students)report=analyzer.generate_grade_report()print(report)

✅ 看看这段代码——即使你没有逐行仔细分析逻辑,也能大致知道它在做什么。这就是好的命名带来的力量:代码本身就是最好的文档。

十一、本篇小结

📝 好的命名是程序员最重要的软技能之一。核心收获:

  1. 遵循PEP 8规范:变量/函数snake_case,类PascalCase,常量UPPER_CASE
  2. 名字要有描述性student_count远好于n
  3. 函数用动词开头get_set_calculate_validate_
  4. 布尔变量用is_/has_前缀:让判断条件读起来像自然语言
  5. 理解下划线约定_internal__name_mangling__magic___
  6. 避免拼音、缩写、匈牙利命名法

💡 每次写代码时,花几秒钟想一个好名字。这个投入会在未来(无论是你自己还是别人)阅读代码时获得成百上千倍的回报。

http://www.jsqmd.com/news/954462/

相关文章:

  • 2026高强度耐磨浇注料厂家选型观察:供应商交付力与场景适配度评估指南 - 企师傅推荐官
  • 告别繁琐操作:用快马AI快速生成图像处理创意原型
  • 微信投票工具推荐,如何高效制作投票活动|火星投票2026防刷零广告实测 - 微信投票小程序
  • Poetry 依赖管理实战:从 pip 迁移的工程化升级
  • http-server-o.bat 最方便启动当前目录的index.html
  • 多组学生物衰老时钟!高精度、可解释、可扩展
  • 武汉名包回收“内幕”:高价靠谱的渠道藏在这里,别再被坑 - 奢侈品交易观察员
  • 大润发购物卡余额别浪费!零钱到账完整操作步骤 - 团团收购物卡回收
  • 用Python搞定PHM 2012轴承数据集:从数据下载到特征提取的保姆级教程
  • # 常州轮胎维修哪家好?金坛薛埠汽修门店实测解析|竞品对比+轮胎选购避坑全攻略 - 国麟测评
  • JetBrains IDE试用期重置终极指南:一键恢复30天免费使用
  • 长清区黄金回收测评:金价975元/克,本地回收价与避坑指南 - 上门黄金回收
  • 点按钮下载
  • AI排序效果总不达标?资深算法工程师首次公开12项可量化调优指标
  • 实战应用,基于快马ai定制wsl环境,快速部署ubuntu下的web开发项目
  • 微电网储能容量与充放电策略联合优化代码包(含Gurobi建模+动态可视化)
  • 2026年洛阳婚礼堂全案设计与宴会酒店升级改造完全指南 - 企业名录优选推荐
  • 2026年广州餐饮点餐小程序多少钱 - 凡科杰建云
  • 2026年深圳生鲜配送小程序怎么做 - 凡科杰建云
  • 2026年路径规划API对比:丰图/高德/百度/腾讯哪家强?实测避坑指南
  • 告别龟速下载!保姆级教程:Windows 10/11下用迅雷搞定Qt 5.14.2离线安装包
  • 独立显卡市场2026:一线品牌显卡有哪些格局再界定
  • 新手如何体验vibe coding?用快马平台描述想法即刻生成可运行代码
  • MATLAB图形界面英文OCR工具:内置9层神经网络,支持多行文本图像自动分割与识别
  • 破解传统鼠控痛点:景隆3S智能鼠饵站方法论如何重构虫控效率? - 资讯纵览
  • 2026年|降AI收藏!学长实测10款AI智能降重工具红黑榜:论文降AI避坑(含免费降低AI率办法) - 降AI小能手
  • 2026 肥城防水补漏哪家好?住建实地测评权威榜单 TOP5|北泰山余脉山地 / 中部丘陵矿区 / 南部汶河冲积平原、肥城高新区渗漏修缮白皮书(6 月专项调研) - 苏易修缮
  • 2026磷酸盐加药装置厂家横评:交付能力与工程适配度深度解析指南 - 企师傅推荐官
  • 星灿智能获千万级融资,三大产业资本加持,破具身智能数据瓶颈领跑家用机器人赛道
  • 告别重复造轮子:用快马ai为keil工程一键生成定时器pwm驱动模块