在嵌套类中使用super()

2024-05-23 17:35:48 发布

您现在位置:Python中文网/ 问答频道 /正文

想象一下:

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。


Tags: nameself定义objectinitisdef错误
3条回答

我不知道A.B为什么不能像它应该的那样对你起作用。。下面是一些有效的shell输出:

>>> 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>

因为B可能永远不会被扩展,所以这应该是有效的:

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

如果类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

相关问题 更多 >