24

これを想像してください:

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

これによりエラーが発生します。

NameError: グローバル名 B が定義されていません。

を試しましA.Bたが、A定義されていないと表示されます。

アップデート:

問題が見つかりました。

私はこのようなクラスを持っていました:

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

    someattribute = B()

そのスコープでは、 A はまだ定義されていません。

4

3 に答える 3

20

AB が正常に動作しない理由がわかりません。動作するシェル出力を次に示します。

>>> 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>
于 2009-12-01T11:04:30.490 に答える
5

Bはそれ自体が拡張されることはない可能性が高いため、これは機能するはずです。

class A(object):
    class B(object):
        def __init__(self):
            super(self.__class__, self).__init__()
于 2009-12-01T10:58:58.470 に答える
2

クラス 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>

記述子の詳細については、http: //users.rcn.com/python/download/Descriptor.htmを参照してください。

于 2009-12-01T19:10:13.877 に答える