类中调用已定义变量时出现NameError问题求助
问题根源:类体中列表推导式的作用域限制
你遇到的这个NameError其实是Python类定义阶段作用域规则的一个小坑。虽然你确实在if块里定义了_norm,但列表推导式在类体中会创建自己的独立局部作用域,这个作用域没办法访问到同一代码块里刚刚定义的_norm变量——简单说,列表推导式“看不到”你在它上方一行定义的_norm。
验证逻辑的修正写法
你可以把列表推导式换成普通的for循环试试,就不会报错了:
class rng(object): _rand_nums = [6,3,2,1] _p = [0.1,2,0.7,0.4] if any(i >= 1 for i in _p): _norm = sum(_p) # 用普通循环替代列表推导式,直接在类体作用域执行 normalized_p = [] for i in _p: normalized_p.append(i/_norm) _p = normalized_p
为什么列表推导式不行?
在Python中,类体是一个特殊的命名空间,而列表推导式(以及生成器表达式、字典/集合推导式)在类定义内部运行时,会创建一个嵌套的作用域,这个作用域无法捕获类体中的临时变量(比如这里的_norm)。而普通的for循环是直接在类体的作用域里执行的,所以能正常访问_norm。
另一种简洁的替代写法
如果你还是想用推导式,可以直接引用类的属性来访问_norm:
class rng(object): _rand_nums = [6,3,2,1] _p = [0.1,2,0.7,0.4] if any(i >= 1 for i in _p): _norm = sum(_p) # 通过类名引用_norm,绕过推导式的作用域限制 _p = [i/rng._norm for i in _p]
不过这种写法依赖于类已被部分定义,虽然能运行,但不如普通循环直观易懂。
额外小提示
你的_p初始值里有个2,这显然不是合法的概率值(概率应在0到1之间),不过这应该是你测试用的示例数据~
内容的提问来源于stack exchange,提问作者PyRsquared
相关产品推荐
相关产品推荐

