在嵌套类中使用 super()

发布于 2024-08-13 01:11:27 字数 511 浏览 7 评论 0原文

想象一下:

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

这会产生一个错误:

NameError: global name B is not defined.

我尝试过 AB,但随后它说 A 未定义。

更新:

我发现了问题。

我有一个这样的类:

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

    someattribute = B()

在该范围内, A 尚未定义。

Imagine this:

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

This creates an error:

NameError: global name B is not defined.

I've tried A.B, but then it says that A is not defined.

Update:

I've found the problem.

I've had a class like this:

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

    someattribute = B()

In that scope, A isn't defined yet.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

一身仙ぐ女味 2024-08-20 01:11:27

我不知道为什么 AB 不能正常工作,因为它应该......以下是一些有效的 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>

I'm not sure why A.B is not working correctly for you, as it should.. Here's some shell output that works:

>>> 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>
述情 2024-08-20 01:11:27

由于 B 可能永远不会扩展自身,因此这应该可行:

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

Since B will likely never be extended itself, this should work:

class A(object):
    class B(object):
        def __init__(self):
            super(self.__class__, self).__init__()
梦归所梦 2024-08-20 01:11:27

如果类 AB 不太可能参与任何多重继承,那么您最好只对构造函数调用进行硬编码:

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>

有关描述符的更多信息,请参阅: rcn.com/python/download/Descriptor.htm" rel="nofollow noreferrer">http://users.rcn.com/python/download/Descriptor.htm

If the class A.B is unlikely to participate in any multiple inheritance, then you're better off just hard-coding the constructor call:

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

But if you really do need to have the full power of super, then you can get what you want by defining a custom descriptor that will initialize the B attribute lazily:

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)

This will cause the B attribute to be instantiated the first time it's accessed, and then reused thereafter:

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

For more info on descriptors, see: http://users.rcn.com/python/download/Descriptor.htm

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文