2014-10-05 92 views
2

假設我有一個來自第三方庫的類A(它是numpy.matrix)。我想用包裝類B擴展它的公共接口。將對象包裝到派生類中

class B(A): 
    def myMethod(self,arg): 
     return 'spam' 

而且,我想從A對象創建B對象。由於B將無法容納更多的屬性,我真的不想返回的目的,用B行爲:

class B(A): 
    def __new__(cls,a): # type(a)==A 
     return a.castTo(B) # pseudo-code 

有沒有辦法做到這一點在Python?

同樣,有沒有辦法將B對象投射到A對象?

+0

相關:http://stackoverflow.com/questions/25394550/adding-methods-to-an-existing-class-instance-or-how-to-subclass-an-instance – 2014-10-05 03:51:46

+1

@NickT:謝謝你。這似乎太複雜了。是不是支持這種基本面向對象的東西的語言?在C++中,它將是一個簡短的單線程。紅寶石相同(AFAIK)。或者Python不以這種方式工作?我很困惑... – 2014-10-05 04:10:09

+0

似乎你應該可以使用裝飾:http://thecodeship.com/patterns/guide-to-python-function-decorators/ – user4107395 2014-10-05 04:55:25

回答

1

您的B班的__new__需要致電A的__new__。這是一個使用內置list類的簡短演示。

class mylist(list): 
    def __new__(cls, obj=None): 
     return list.__new__(cls, obj) 

    def mymethod(self, msg): 
     print msg, id(self) 


def main(): 
    a = mylist('abc') 
    print a, id(a) 
    a.mymethod('hello') 


if __name__ == '__main__': 
    main() 

如果你只是想簡單的功能添加到現有的類的實例,你可以做這樣的事情。

class A(object): 
    pass 

def silly(arg=None): 
    print 'This is silly', arg 

b = A() 
b.my = silly 
b.my() 

注意b.my它只是一個功能,而不是一個方法,所以它不你叫它獲得通過自我。但是,你可以通過它 「手工」 做b.my(b)


編輯

作爲替代書寫list.__new__(cls, obj),你可以調用super()功能:

def __new__(cls, obj=None): 
    return super(mylist, cls).__new__(cls, obj) 

但在大多數使用基類名稱的情況越來越簡單。我想可能是一個理由更喜歡super(),但我不夠專業這方面的專家說。 :)

+0

謝謝,第一部分是我期待的答案。我無法在互聯網上找到任何東西。我用__new_返回[],而不是列表.__新__(cls,obj),所以我最終得到了一個基類對象。 – 2014-10-05 22:33:59

+0

我在[文檔](https://www.python.org/download/releases/2.2.3/descrintro#__new__)中瞭解到Guido的語法,但這不是我經常使用的東西。 – 2014-10-06 12:56:49