内部类的实例作为外部类方法的默认值



我想使用内部类的实例(在本例中为namedtuple,尽管用class定义的内部类会出现完全相同的症状(作为外部类方法(在本案中为构造函数(的默认值。然而,当从不同的模块导入此代码时,似乎缺少外部类定义。

示例:

# mymodule.py
from typing import NamedTuple, Tuple
class IdSignal():
Cfg = NamedTuple('IdSignalCfg', [
('nfft', int),
('limits', Tuple[float, float]),
('min_spacing', float),
('nmix', int)])
Cfg.__new__.__defaults__ = (
512,
(1500, 7500),
200,
3
)
def __init__(self, cfg = IdSignal.Cfg()):
self.cfg = cfg

现在执行import mymodule投掷:

Exception has occurred: NameError
name 'IdSignal' is not defined
File "...", line 18, in IdSignal
def __init__(self, cfg = IdSignal.Cfg()):
File "...", line 5, in <module>
class IdSignal():
...
import mymodule

令人困惑的是,pylint和mypy都没有识别出上面代码中的任何错误。

这可以通过其他方式实现吗?

我知道我可以使用None作为默认值,并在构造函数中实例化IdSignal.Cfg。如果这是唯一的解决方案,我想了解为什么上面的代码失败了?

在定义__init__时,名称IdSignal尚未绑定到类。(直到class语句的整个主体被求值,并且求值的结果被传递给相关元类,才会发生这种情况。(然而,Cfg还不是类属性;它只是定义__init__的同一"范围"中的一个名称,因此不需要限定该名称。

def __init__(self, cfg=Cfg()):
self.cfg = cfg

类似的class语句

class Foo:
x = 3
def __init__(self, y):
self.y = y

大致相当于

# These names don't really matter, but I'm using different
# names than what the attributes will be just to emphasize
# the point that they really are distinct objects before
# the new class is ever created.
class_x = 3
def some_init(self, y):
self.y = y
Foo = type('Foo', (object,), {'__init__': some_init, 'x': class_x})

请注意,Foo这个名称直到最后才出现。class语句不像模块或函数那样定义新的作用域,但class语句中定义的名称也不是任何封闭作用域的一部分;将它们视为临时名称,一旦创建了类,这些名称就会被丢弃。

最新更新