在派生 class 中访问基础 class 属性 - 在 "class scope" 中
Access base class attribute in derived class - in "class scope"
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 没有帮助 - 在模块范围内移动它会起作用,但会破坏具有 classes 的目的。那么该怎么做呢?
编辑:来自 Java,所以 classes 的范围规则让我头疼 - 如果能提供简报,我们将不胜感激。顺便说一句:
class Derived(InnerBase): pass
Derived._var = InnerBase._var | {'baz'}
但这不是优雅的顶峰。
相关:Nested classes' scope? - 但这里我们特别想访问我们的父级 class(而不是 Outer 类型)
EDIT2:我真正想要的是一个类似于 _var = __class__._var
的语法(或 hack),或者关于 为什么 它不存在的解释
当你把它放在一个方法中时,它就起作用了。
def __init__(self):
_var = Outer.InnerBase._var | {'baz'}
#_var = super(Outer.Derived, self)._var | {'baz'} # or with super
print(_var)
所以我的印象是,一切都是关于初始化的。
Python 从不在封闭的 class 语句中搜索名称。 Mark Lutz 在他对 Python 的介绍(学习 Python)中使用首字母缩略词 LEGB 来总结范围:Python 搜索本地范围,然后是任何封闭 def
语句的局部范围,然后是全局范围,最后是内置范围。 Class 个语句被排除在这个范围列表之外; Python 不搜索包含 class 语句的名称。
一个解决方案是取消嵌套您的 classes。在 Python 中,使用非嵌套的 classes 通常因其简单性而受到青睐。但是,当然,嵌套 classes 也是有充分理由的。为什么要嵌套 InnerBase
?我想知道您是否因为在 Java 中的经验而嵌套了 class。以下内容是否也适合您?
class InnerBase(object):
_var = {'foo', 'bar'}
class Derived(InnerBase):
_var = InnerBase._var | {'baz'}
>>> Derived._var
set(['baz', 'foo', 'bar'])
当您将这两个 class 语句嵌套在另一个 class 语句下时,它们将被排除在名称搜索之外,因为它们已成为更大的 class 语句的一部分,因此排除在各种范围的搜索之外。
您可以绕过 class
语句并显式调用 type
。
class Outer(object):
class InnerBase(object): _var = {'foo', 'bar'}
Derived = type('Derived',
(InnerBase,),
{'_var': InnerBase._var | {'baz'}}
)
这是有效的,因为 Derived._var
不是通过定义 Derived
的 class
语句中的赋值语句设置的,而是从您在与 [相同的环境中创建的字典中导入的=16=]本身。
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 没有帮助 - 在模块范围内移动它会起作用,但会破坏具有 classes 的目的。那么该怎么做呢?
编辑:来自 Java,所以 classes 的范围规则让我头疼 - 如果能提供简报,我们将不胜感激。顺便说一句:
class Derived(InnerBase): pass
Derived._var = InnerBase._var | {'baz'}
但这不是优雅的顶峰。
相关:Nested classes' scope? - 但这里我们特别想访问我们的父级 class(而不是 Outer 类型)
EDIT2:我真正想要的是一个类似于 _var = __class__._var
的语法(或 hack),或者关于 为什么 它不存在的解释
当你把它放在一个方法中时,它就起作用了。
def __init__(self):
_var = Outer.InnerBase._var | {'baz'}
#_var = super(Outer.Derived, self)._var | {'baz'} # or with super
print(_var)
所以我的印象是,一切都是关于初始化的。
Python 从不在封闭的 class 语句中搜索名称。 Mark Lutz 在他对 Python 的介绍(学习 Python)中使用首字母缩略词 LEGB 来总结范围:Python 搜索本地范围,然后是任何封闭 def
语句的局部范围,然后是全局范围,最后是内置范围。 Class 个语句被排除在这个范围列表之外; Python 不搜索包含 class 语句的名称。
一个解决方案是取消嵌套您的 classes。在 Python 中,使用非嵌套的 classes 通常因其简单性而受到青睐。但是,当然,嵌套 classes 也是有充分理由的。为什么要嵌套 InnerBase
?我想知道您是否因为在 Java 中的经验而嵌套了 class。以下内容是否也适合您?
class InnerBase(object):
_var = {'foo', 'bar'}
class Derived(InnerBase):
_var = InnerBase._var | {'baz'}
>>> Derived._var
set(['baz', 'foo', 'bar'])
当您将这两个 class 语句嵌套在另一个 class 语句下时,它们将被排除在名称搜索之外,因为它们已成为更大的 class 语句的一部分,因此排除在各种范围的搜索之外。
您可以绕过 class
语句并显式调用 type
。
class Outer(object):
class InnerBase(object): _var = {'foo', 'bar'}
Derived = type('Derived',
(InnerBase,),
{'_var': InnerBase._var | {'baz'}}
)
这是有效的,因为 Derived._var
不是通过定义 Derived
的 class
语句中的赋值语句设置的,而是从您在与 [相同的环境中创建的字典中导入的=16=]本身。