2009-12-01 76 views
19

想象一下:在嵌套类使用超()

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

在该范围内,但是,尚不能确定。

+0

使用Python 2.6两'AB',以及'自.__ class__',似乎上班。 – 2009-12-01 11:07:05

+0

'A.B'适合我。但是你确定你需要多重继承和'super'吗?除非你真的需要它,否则不要跳到MI世界(通常不会)。如果你这样做,你需要在'__init__'中允许并传递'* args'和'** kwargs'。 – bobince 2009-12-01 11:11:12

+0

A没有在它自己的类块中定义,所以A类变量'_inner = B()'将不起作用。 – u0b34a0f6ae 2009-12-01 11:20:32

回答

16

我不知道为什么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> 
5

由于B将可能永远不会被延长本身,这应该工作:

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

如果AB类是不可能参与任何多重继承,那么你最好还是先硬编码的构造函数调用:

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