python - 来自dict理解的Python类变量引用子类
问题描述
考虑这段代码
class A:
class B:
foo = 1
bar = {x: B for x in range(5)}
这将产生一个错误,指出B
未定义。但是,当调试器在相应行停止时,在 REPL 上,我可以很好地运行该代码。这似乎是一些嵌套/范围问题,但我不明白。
有人可以解释发生了什么以及如何解决这个问题吗?
解决方案
dict 理解隐式定义了一个匿名函数。在该函数的主体内,B
是一个自由变量。变量查找规则规定 的值B
取自定义 的最近的封闭范围,B
但语句class
没有定义范围(尽管它确实定义了一个类似于适当范围的临时命名空间)。匿名函数本地范围的下一个范围是全局范围,其中B
未定义。
为了避免绑定问题,定义一个B
作为参数的函数,并让该函数执行 dict 理解:
bar = (lambda cls: {x: cls for x in range(5)})(B)
现在,B
is 可以在class
语句的当前命名空间中找到(避免了范围规则),并且cls
被定义在 lambda 表达式定义的匿名函数的范围内,现在可以在 dict 使用的范围堆栈中找到理解。换句话说,由推导式创建的匿名函数是对 lambda 表达式函数范围的闭包。
也就是说,嵌套类在 Python 中并不常见。您可以B
在全局范围内定义以解决这种情况下的问题。
推荐阅读
- python - Django 添加新模型,异常类型:OperationalError 异常值:没有这样的表:
- python - 如何使用 groupby 减去列中的值
- java - Spring boot rest api - 将 getResultList() 转换为 Map 以显示响应而不创建 java 类的最佳方法?
- c - 如何在C中正确关闭文件
- excel - 如何将图表中一个条形的颜色设置为透明?
- php - 组织数据库来存储/获取用户事件和日期
- java - 如何将调用注释的类名和方法作为“值”传递给注释属性
- mysql - Express mysql connection err Error: connect ETIMEDOUT on Mac OS
- typescript - 打字稿简单的减速器组成
- javascript - 只允许数字和逗号