在嵌套类中使用super()

26 投票
3 回答
9269 浏览
提问于 2025-04-15 16:33

想象一下:

class A(object):
    class B(object):
        def __init__(self):
            super(B, self).__init__()

这会产生一个错误:

NameError: global name B is not defined.

我试过 A.B,但它说 A 没有定义。

更新:

我找到了问题所在。

我有一个这样的类:

class A(object):
    class B(object):
        def __init__(self):
            super(B, self).__init__()

    someattribute = B()

在那个范围内,A 还没有定义。

3 个回答

2

如果类 A.B 不太可能参与多重继承,那么你可以直接写死构造函数的调用,这样更简单:

class A(object):
    class B(object):
        def __init__(self):
            object.__init__(self)

但是如果你真的需要使用 super 的全部功能,那么你可以通过定义一个自定义描述符来实现,这样可以懒加载 B 属性:

class LazyAttribute(object):
    def __init__(self, func, *args, **kwargs):
        self._func = func
        self._args = args
        self._kwargs = kwargs
        self._value = None

    def __get__(self, obj, type=None):
        if self._value is None:
            print 'created', self._value
            self._value = self._func(*self._args, **self._kwargs)
        return self._value

class A(object):
    class B(object):
        def __init__(self):
            super(A.B, self).__init__()

    someattribute = LazyAttribute(B)

这样做会让 B 属性在第一次被访问时才被创建,以后再访问时就会重复使用:

>>> print A.someattribute
created <__main__.B object at 0x00AA8E70>
<__main__.B object at 0x00AA8E90>
>>> print A().someattribute
<__main__.B object at 0x00AA8E90>

想了解更多关于描述符的信息,可以查看这个链接: http://users.rcn.com/python/download/Descriptor.htm

5

因为B可能永远不会被扩展,所以这样做应该没问题:

class A(object):
    class B(object):
        def __init__(self):
            super(self.__class__, self).__init__()
20

我不太明白为什么 A.B 对你来说不正常,因为它应该是可以正常工作的。这里有一些可以正常运行的命令行输出:

>>> class A(object):
...   class B(object):
...     def __init__(self):
...       super(A.B, self).__init__()
...   def getB(self):
...     return A.B()
... 
>>> A().getB()
<__main__.B object at 0x100496410>

撰写回答