Использование super() в вложенных классах
Представьте себе следующее:
class A(object):
class B(object):
def __init__(self):
super(B, self).__init__()
Это создает ошибку:
NameError: global name B is not defined.
Я пробовал A.B
, но потом он говорит, что A
не определен.
Update:
Я нашел проблему.
У меня был класс вроде этого:
class A(object):
class B(object):
def __init__(self):
super(B, self).__init__()
someattribute = B()
В этой области действия A еще не определено.
Ответы
Ответ 1
Я не уверен, почему 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>
Ответ 2
Поскольку B, скорее всего, никогда не будет распространен, это должно работать:
class A(object):
class B(object):
def __init__(self):
super(self.__class__, self).__init__()
Ответ 3
Если класс A.B вряд ли будет участвовать в любом множественном наследовании, то вам лучше просто жестко кодировать вызов конструктора:
class A(object):
class B(object):
def __init__(self):
object.__init__(self)
Но если вам действительно нужна полная мощь супер, то вы можете получить то, что хотите, указав собственный дескриптор, который будет инициализировать атрибут 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