【发布时间】:2016-11-02 18:14:05
【问题描述】:
考虑这段代码:
class A:
B = 42 # or whatever
class C:
a = B # wont find `B` here
这行不通,因为在class C 中找不到B。
您也不能使用A.B,因为此时A 是未知的,因为它仍在构建中,因此它不在全局命名空间中。在成员函数内部,这将起作用,因为在您执行该代码时,全局名称 A 可能已注册。但是,我明确要求直接访问,而不是在成员函数内部。
那么,在这样的嵌套类构造中,还有其他方法可以访问外部命名空间吗?
我想答案可能是否定的,或者至少不是以一种干净的方式。我在class C 中添加了print(locals()),使用Python 2,我得到{'__module__': '__main__'},使用Python 3,我得到{'__qualname__': 'A.C', '__module__': '__main__'}。所以无论是本地还是全局都不会给我访问父本地命名空间的权限。
关于不干净的方式:sys._getframe(1).f_locals["B"] 将起作用。那是 A 类在构建时的本地人,B 在那里。
那么,如果没有干净的方法来做到这一点,还有什么其他的解决方案?我可以直接在全局命名空间中声明所有类,但我不喜欢这样(对于我的特定用例)。我可以将它们移动到子模块中并将它们导入A。但这会使代码阅读起来更加复杂。还有其他解决方案吗?
所以,我想它总是一样的,除非我不展示一个真实世界的例子,否则人们不会相信这样的用例是如何发生的。所以,这里是(via):
class structs:
# .... many more
class _anonymous_label(ctypes.Structure):
_fields_ = [
('lb_type', ctypes.c_int),
('lb_str', ctypes.POINTER(ctypes.c_byte))]
class _anonymous_labellist(ctypes.Structure):
_fields_ = [
('ll_nlabels', ctypes.c_int),
('ll_label', ctypes.POINTER(_anonymous_label))] # error
# .... many more
【问题讨论】:
-
看看这个例子是多么微不足道:你有什么用例不是微不足道的?
-
我其实有点好奇。这和闭包有什么区别?内部函数在哪里可以访问外部范围?我尝试使用元类并使用它的 _new_ 来设置 Ca =B,但即使这样也令人窒息 - 未定义全局名称“B”。我确实意识到类声明本身不是函数,但范围方面“看起来一样”。另外,Python 3(我在 2)没有更改嵌套范围查找吗?
-
class structs: ...- 你为什么要这样做?即使您希望其中的类位于它们自己的命名空间中,这也是模块系统的工作,而不是嵌套类。制作一个structs模块。 -
@JLPeyret:这和方法一样,它不在类中查找变量。嵌套在类作用域内的作用域永远不会在类作用域中查找变量。
-
啊,是的。知道了。需要 self 或类名。那就不那么奇怪了。
标签: python namespaces