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.
3 Answers 3
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>
Comments
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__()
Comments
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
A.B, as well asself.__class__, seem to work.A.Bworks fine for me. But are you sure you need multiple inheritance andsuperhere? Don't jump to the MI world unless you really need it (you usually don't). If you do go that way you need to allow and pass-through*argsand**kwargsin your__init__._inner = B()will not work.