class Outer(object):
class InnerBase(object): _var = {'foo', 'bar'}
class Derived(InnerBase):
_var = _var | {'baz'} # NameError: name '_var' is not defined
_var = InnerBase._var | {'baz'} # name 'InnerBase' is not defined
_var = Outer.InnerBase._var | {'baz'} # free variable 'Outer'
# referenced before assignment in enclosing scope
在Outer
中移动_var并没有帮助 - 在模块范围内移动它会起作用但是会破坏课程的目的。那怎么办呢?
class Derived(InnerBase): pass
Derived._var = InnerBase._var | {'baz'}
但它并不是优雅的顶峰。
相关:Nested classes' scope? - 但在这里我们特别想要访问我们的父类(而不是外部类型)
EDIT2:我实际上是一个类似_var = __class__._var
的语法(或黑客),或者为什么不存在
答案 0 :(得分:3)
Python从不在封闭的类语句中搜索名称。 Mark Lutz使用首字母缩略词LEGB来概括他对Python(学习Python )的介绍中的范围:Python搜索本地范围,然后搜索任何封闭的def
语句的本地范围,然后是全局范围,最后是内置范围。类范围列表中不包括类语句; Python不会为名称搜索封闭的类语句。
一种解决方案是取消嵌套您的课程。在Python中,使用非嵌套类通常是首选,因为它的简单性。但是,当然,也有很好的理由来嵌套课程。你为什么要嵌套InnerBase
?我想知道你是否可能因为你在Java方面的经验而嵌套了那个类。以下是否也适合您?
class InnerBase(object):
_var = {'foo', 'bar'}
class Derived(InnerBase):
_var = InnerBase._var | {'baz'}
>>> Derived._var
set(['baz', 'foo', 'bar'])
在将这两个类语句嵌套在另一个类语句下的那一刻,它们将从名称搜索中排除,因为它们已成为较大类语句的一部分,因此被排除在搜索各种范围之外。
答案 1 :(得分:2)
您可以绕过class
语句,并使用对type
的显式调用。
class Outer(object):
class InnerBase(object): _var = {'foo', 'bar'}
Derived = type('Derived',
(InnerBase,),
{'_var': InnerBase._var | {'baz'}}
)
这是有效的,因为Derived._var
未通过定义class
的{{1}}语句中的赋值语句设置,而是从您在与{{1}相同的环境中创建的字典中导入本身。
答案 2 :(得分:-1)
当你把它放在一个方法中时,它可以工作。
def __init__(self):
_var = Outer.InnerBase._var | {'baz'}
#_var = super(Outer.Derived, self)._var | {'baz'} # or with super
print(_var)
所以我的印象就是初始化。