不能直接用 keyword.iskeyword() 判断变量名合法性;它仅检测是否为保留关键字,不校验标识符语法,须配合 str.isidentifier() 使用,且需先确保输入为字符串。

keyword.iskeyword() 能直接判断变量名合法性吗?
不能直接用 keyword.iskeyword() 判断“能否作为变量名”——它只检查是否为 Python 保留关键字,不校验是否符合标识符语法(比如数字开头、含非法字符等)。你得先确保字符串是合法标识符,再查是否为关键字。
常见错误是传入 "123abc" 或 "class!" 这类非合法标识符,keyword.iskeyword() 会返回 False,但它们根本不能当变量名用。所以必须组合 str.isidentifier() 一起用。
-
str.isidentifier()检查是否符合变量命名规则(如不能以数字开头、不能含空格或运算符) -
keyword.iskeyword()检查是否为保留字(如"def"、"yield") - 两者都为
True才算“合法变量名” —— 实际上,isidentifier()为False就直接否决,无需再调iskeyword()
动态检查变量名的最小可靠函数怎么写?
写一个函数,输入字符串,返回是否可安全用作变量名:
import keyword
def is_valid_varname(name):
return isinstance(name, str) and name.isidentifier() and not keyword.iskeyword(name)
注意三个条件缺一不可:
立即学习“Python免费学习笔记(深入)”;
-
isinstance(name, str)防止传入None或数字导致.isidentifier()报AttributeError -
name.isidentifier()是前置门槛,过滤掉所有语法非法名 -
not keyword.iskeyword(name)排除"if"、"for"等保留字
例如:is_valid_varname("my_var") → True;is_valid_varname("class") → False;is_valid_varname("2abc") → False(因 "2abc".isidentifier() 为 False)
图片提示词生成器?不止如此。 马甲系统 —— 把脑海中的画面,翻译成AI能理解的专业表达。 用得越多,它越懂你:首次需要多问几句确认方向,用久了几乎一说就懂。 用得越多,它越快:缓存机制让后续对话越来越省。 RAG进化:成功案例持续入库,越跑越聪明。 输入「新手指南」查看完整功能介绍
为什么不能只依赖 keyword.kwlist 做 in 判断?
用 name in keyword.kwlist 看起来直观,但有隐患:
-
keyword.kwlist是列表,每次in是 O(n) 查找,而keyword.iskeyword()内部用的是集合查找,O(1),性能更稳 -
keyword.kwlist不包含未来可能新增的关键字(如 Python 3.12 加了"match"和"case"),但keyword.iskeyword()总是同步标准库版本 - 手动维护
kwlist复制容易漏更新,尤其跨 Python 版本时
所以别绕开 keyword.iskeyword(),它就是为此设计的唯一正解。
在 eval/exec 或动态赋值前必须做这个检查吗?
必须。如果你从用户输入、配置文件或 API 接收变量名并用于 exec()、setattr() 或构建表达式,跳过检查会导致运行时报错甚至执行意外代码。
典型崩溃场景:
-
exec("class = 42")→SyntaxError: invalid syntax -
setattr(obj, "def", 1)→ 属性名本身合法,但后续用obj.def会语法错误 - 用用户输入拼接 f-string 或格式化字符串时,若变量名是关键字,Jinja2 或其他模板引擎可能静默失败或报错位置难定位
真正容易被忽略的是:检查必须在字符串进入任何动态执行上下文之前完成,而不是等 SyntaxError 抛出来再处理 —— 那时堆栈已深,调试成本高,且可能暴露内部逻辑。


















