一、开篇:标识符——你给代码取的所有名字
今天我们要聊的标识符(identifier),正好是关键字之外的另一面:你自己给代码元素取的名字。
变量名、函数名、类名、模块名、参数名——这些都是标识符。你写的每一行代码几乎都包含标识符。理解标识符的规则,对于写出正确、可读、专业的python代码至关重要。
二、什么是标识符
2.1 定义
标识符就是程序员为代码中的各种元素(变量、函数、类、模块等)自定义的名称。标识符的作用是标识——用名字来区分和引用代码中的不同实体。
# 这些"名字"都是标识符
student_name = '小明' # 变量名(标识符)
def calculate_average(): # 函数名(标识符)
total_score = 0 # 变量名(标识符)
for score in scores: # 变量名(标识符)
total_score += score
return total_score
class studentrecord: # 类名(标识符)
def __init__(self, name): # 方法名 + 参数名(都是标识符)
self.name = name # 属性名(标识符)
2.2 标识符 vs 关键字
最简单的区分方式:除了35个关键字,其他一切合法的名字都是标识符。
# 用程序判断一个字符串是否是合法的标识符
import keyword
def check_identifier(name):
"""检查一个字符串是否能用作标识符"""
if keyword.iskeyword(name):
return f'"{name}" 是关键字,不能用作标识符'
elif name.isidentifier():
return f'"{name}" 是合法的标识符'
else:
return f'"{name}" 不是合法的标识符'
# 测试
print(check_identifier('hello')) # 合法的标识符
print(check_identifier('if')) # 是关键字
print(check_identifier('123abc')) # 不是合法的标识符
print(check_identifier('my-var')) # 不是合法的标识符
str.isidentifier() 是python内置的字符串方法,用来判断一个字符串是否可以作为合法的标识符。
三、标识符的合法性规则
3.1 三条硬性规则
规则一:第一个字符必须是字母(a-z, a-z)或下划线(_)
# ✅ 合法的开头 name = '正确' # 字母开头 _name = '正确' # 下划线开头 name = '正确' # 大写字母开头 变量 = '正确' # python 3支持中文变量名(但不推荐) # ❌ 非法的开头 1name = '错误' # 数字开头 @name = '错误' # 特殊符号开头 -name = '错误' # 连字符开头
规则二:后续字符可以是字母、数字(0-9)或下划线
# ✅ 合法的标识符 student1 = '正确' # 字母+数字 student_name = '正确' # 字母+下划线+字母 _file_2 = '正确' # 下划线+字母+下划线+数字 max_size_100 = '正确' # 大写字母+下划线+数字 # ❌ 非法的标识符 student-name = '错误' # 连字符 student.name = '错误' # 句号 student name = '错误' # 空格 student@home = '错误' # @符号
规则三:不能是python关键字
# ❌ 这些都是关键字,不能用作标识符 if = 10 class = '历史课' for = 3 true = '假' # python 3中true是关键字,不能赋值 none = '有值' # none也是关键字
3.2 大小写敏感
python标识符是严格区分大小写的:
# 这是三个不同的变量! name = '小明' name = '小红' name = '小刚' print(name) # 小明 print(name) # 小红 print(name) # 小刚 # 常见的pep 8惯例 max_size = 100 # 常量用全大写 max_size = 100 # 普通变量用小写
📝 虽然 python 允许你同时使用 name、name 和 name,但强烈不建议在一个代码文件中这样做——这极易造成混淆。大小写在python中是用来区分不同类型的标识符的(如全大写代表常量,首字母大写代表类名),而不是用来创建相似名字的。
四、标识符的命名约定
除了硬性规则,python社区还有一套广泛接受的约定(conventions)。遵守这些约定能让你的代码更容易被其他python开发者阅读。
4.1 各类标识符的命名风格
# 变量名、函数名、方法名:snake_case(蛇形命名)
student_count = 42
def calculate_average(scores):
pass
# 类名、异常名:pascalcase(帕斯卡命名)
class studentrecordmanager:
pass
class invalidinputerror(exception):
pass
# 常量:upper_snake_case(大写蛇形命名)
max_retry_count = 3
database_url = 'postgresql://localhost/mydb'
# 模块名:简短的小写字母(可加下划线)
import data_utils
import http_client
# 包名:简短的小写字母(不加下划线)
# 例如:mypackage, utils, models
4.2 下划线前缀的特殊含义
class myclass:
def __init__(self):
self.public_attr = '公共属性' # 公开访问
self._internal_attr = '内部属性' # _ 前缀:约定"内部使用"
self.__private_attr = '私有属性' # __ 前缀:名称改写
def public_method(self):
"""公开方法"""
pass
def _internal_method(self):
"""内部方法——约定不在类外部调用"""
pass
def __private_method(self):
"""私有方法——python自动改写名称"""
pass
💡 关于下划线约定的详细解释,可以回顾第13篇文章"命名规范与命名习惯",里面有完整的讲解。
4.3 避免使用的命名模式
# ❌ 避免用双下划线开头和结尾(保留给python的魔术方法)
# 不要自己创建类似 __name__ 这样的标识符
class badclass:
def __my_custom_magic__(self): # 危险!可能在未来python版本中变成关键字
pass
# ❌ 避免下划线后跟大写字母(保留给某些特定用途)
_private = '虽然合法,但不推荐'
# ❌ 避免单个下划线后跟数字(有些代码检查工具会警告)
_1st_place = '不推荐'
五、unicode标识符
5.1 python 3支持中文标识符
从python 3开始,标识符完全支持unicode字符。这意味着你可以用中文来命名变量和函数:
# python 3支持中文标识符(但不推荐在生产代码中使用)
学生姓名 = '小明'
年龄 = 20
def 打招呼(名字):
print(f'你好,{名字}!')
打招呼(学生姓名) # 你好,小明!
技术上完全可行,但大多数python项目不使用中文标识符,原因:
- 代码可能需要在不同语言环境的系统上运行
- 中文输入比英文慢(频繁切换输入法)
- python社区的传统和习惯
- 国际化协作的障碍
5.2 unicode标识符的规则
python使用unicode标准中的规则来判定哪些字符可以作为标识符。总体上:
- 字母类字符(包括各国文字)可以作为标识符
- 数字类字符不能作为开头
- 连接符类字符(如下划线)可以使用
- emoji不能作为标识符
# ✅ 合法(但不推荐) café = '法语单词' naïve = '分音符' γ = 0.57721 # 希腊字母gamma # ❌ 非法 🐍 = 'python' # emoji不能用作标识符
⚠️ 在日常开发中,**坚持使用ascii字符(a-z, a-z, 0-9, _)**是最安全、最通用的做法。
六、内置标识符和内置函数名
6.1 python的内置函数名不是关键字
这一点经常被混淆。print、len、sum、list 等虽然是python的内置函数,但它们不是关键字。这意味着你可以(虽然不应该)把它们用作变量名:
# 技术上合法,但导致内置函数无法使用
print = '我把print重定义了'
# print('hello') # typeerror! print现在是字符串,不能调用
# 恢复原来的print
del print # 删除变量print,就恢复了对内置print的访问
print('现在print又正常了')
6.2 应该避免用作标识符的内置名称
以下是常见的内置名称,虽然可以用作标识符,但建议不要这样做:
# 不要用这些内置名称作标识符
# 常用函数
# print, input, len, sum, max, min, abs, round
# type, int, str, float, bool, list, dict, set, tuple
# range, enumerate, zip, map, filter, sorted, reversed
# open, file, id, dir, help, exit, quit
# object, property, classmethod, staticmethod
# ❌ 示例:遮盖了内置函数
list = [1, 2, 3] # 变量名list遮盖了内置函数list()
# list('hello') # typeerror! list现在是列表对象
# ✅ 变通方法
# 如果确实需要用这些词作变量名,在后面加下划线
list_ = [1, 2, 3] # 尾部加下划线
type_ = '学生' # 尾部加下划线
七、标识符作用域
7.1 什么是作用域
标识符的作用域(scope)是指"这个标识符在代码中的哪些地方是可见的"。python有四种作用域,按从内到外的顺序,即legb规则:
- local:函数内部定义
- enclosing:外层函数(嵌套函数)
- global:模块(文件)级别
- built-in:python内置
# 四层作用域示例
x = '全局变量' # global作用域
def outer_function():
y = '外层函数变量' # enclosing作用域
def inner_function():
z = '内层函数变量' # local作用域
print(z) # 访问local
print(y) # 访问enclosing
print(x) # 访问global
print(len) # 访问built-in
inner_function()
outer_function()
7.2 标识符查找顺序
当python遇到一个标识符时,它按照legb的顺序查找:
- 先在local作用域找
- 找不到就去enclosing找
- 再找不到去global找
- 最后去built-in找
- 都找不到就报
nameerror
7.3 命名冲突的处理
# 局部变量会屏蔽全局变量
count = 100 # 全局
def my_function():
count = 10 # 局部——这个名字在函数内部"屏蔽"了全局count
print(f'内部count: {count}')
my_function() # 内部count: 10
print(f'全局count: {count}') # 全局count: 100
八、标识符的常见陷阱
8.1 长得像的字符
# 这些看起来一样,其实不一样! # 注意区分: # 数字 0 vs 字母 o(大写的o) # 数字 1 vs 字母 l(小写的l)vs 字母 i(大写的i) # ❌ 非常容易混淆 o0 = '一个是字母o,一个是数字0' il = '一个是大写i,一个是小写l'
8.2 不可见字符
# 有些时候,复制粘贴代码可能会带入不可见的unicode字符 # 例如:零宽空格(u+200b)、零宽连接符(u+200c) # 如果遇到奇怪的syntaxerror, # 尝试在ide中开启"显示不可见字符"功能
8.3 过度长的标识符
虽然python没有明确限制标识符长度,但过长的名字不好:
# ❌ 太长了 the_total_number_of_active_users_in_the_current_session = 42 # ✅ 合理的长度 active_user_count = 42 session_active_users = 42
💡 一个好的标识符长度通常在8-25个字符之间。太短说不清含义(如 a、t),太长影响可读性。
九、实战:审核一段代码的标识符
让我们一起来审核一段代码,找出所有标识符以及其中可能存在的问题:
# 原始代码(有一些命名问题)
import keyword
class user_manager: # 类名应该是pascalcase
max_user_count = 100 # 常量应该全大写,这个混合了
def __init__(self, name, email, 1st_login=false):
# 参数name应该是name(小写)
# 参数email应该是email(小写)
# 参数1st_login不合法(数字开头)
self.name = name
self.email = email
self._1st_login = false
def get_users(self): # 方法名应该是snake_case
"""获取用户列表"""
list = [] # 变量名遮盖了内置函数list()
for i in range(10): # 循环变量i可以接受
list.append(i)
return list
修复后的代码:
import keyword
class usermanager: # ✅ pascalcase类名
max_user_count = 100 # ✅ 全大写常量
def __init__(self, name, email, is_first_login=false):
# ✅ snake_case参数名
self.name = name
self.email = email
self.is_first_login = is_first_login # ✅ 避免数字开头
def get_users(self): # ✅ snake_case方法名
"""获取用户列表"""
user_list = [] # ✅ 避免遮盖内置函数
for i in range(10):
user_list.append(i)
return user_list
十、本篇小结
✅ 标识符是你每天写代码时都在创造和使用的东西。核心收获:
- 三条硬性规则:字母或下划线开头、后续可用字母数字下划线、不能是关键字
- 大小写敏感:
name、name、name是三个不同的标识符 - 命名约定:变量/函数
snake_case,类pascalcase,常量upper_case - 避免遮盖内置名称:不要用
list、str、print等作为标识符 - legb作用域规则:local → enclosing → global → built-in
- 中文标识符可行但不推荐:生产代码中请用英文命名
标识符的规则很简单,但写好标识符却是区分新手和专家的关键标志。
以上就是python标识符的定义规则与使用注意事项详解的详细内容,更多关于python标识符定义规则与使用的资料请关注代码网其它相关文章!
发表评论