2009-12-01 75 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