2011-04-19 40 views
1

我有一個基類,Python中得出幾個:問題有關Python和類

class Base: 
    def Foo(self): 
     pass 

# First derived class 
class Der1(Base): 
    def OwnFoo(self): 
     # Do something 1 
    def OwnFoo2(self): 
     # Do something 2 

    def Foo(self): 
     # Do something 3 

# Second derived class 
class Der2(Base): 
    def OwnFoo(self): 
     # Do something 1 
    def OwnFoo2(self): 
     # Do something 2 

    def Foo(self): 
     # Do something 3 

的問題是:

我在Der1一些預定義的代碼。從Der2幾乎所有的功能都一樣。我怎樣才能用更少的代碼編寫這個?

我無法將該代碼添加到父級。不應該觸摸父類。

例如,Der2.OwnFoo不一樣Der1.OwnFoo,也許有一些建築在Python只是從第一級呼叫OwnFoo,而不是寫一遍代碼?


我無法改變的Der1Der2父!它應該是Base

+0

它是一門功課? – eumiro 2011-04-19 13:25:35

回答

3

既然你可以不改變繼承結構,創建一個包含通用代碼的幫助類,並通過composition而不是繼承來包含它。

# Common code goes in this new class 
class DerHelper: 
    def __init__(self, parent): 
     self._parent = parent 
    def OwnFoo(self): 
     print 'Do something 1', self._parent 
    def OwnFoo2(self): 
     print 'Do something 2', self._parent 
    def Foo(self): 
     print 'Do something 3', self._parent 

# First derived class 
class Der1(Base): 
    def __init__(self): 
     # include helper class by composition 
     self._helper = DerHelper('Der1') 
    def OwnFoo(self): 
     self._helper.OwnFoo() 
    def OwnFoo2(self): 
     self._helper.OwnFoo2() 
    def Foo(self): 
     self._helper.Foo() 

# Second derived class 
class Der2(Base): 
    def __init__(self): 
     # include helper class by composition 
     self._helper = DerHelper('Der2') 
    def OwnFoo(self): 
     self._helper.OwnFoo() 
    def OwnFoo2(self): 
     self._helper.OwnFoo2() 
    def Foo(self): 
     self._helper.Foo() 

當然,您可以將引用傳遞給父代而不是字符串。我只是這樣做了演示目的。

用法:

d = Der1() 
d.OwnFoo() 
d.OwnFoo2() 
d.Foo() 

d = Der2() 
d.OwnFoo() 
d.OwnFoo2() 
d.Foo() 

輸出:

Do something 1 Der1 
Do something 2 Der1 
Do something 3 Der1 
Do something 1 Der2 
Do something 2 Der2 
Do something 3 Der2 
+0

令人敬畏的例子! – jathanism 2011-04-19 14:01:59

0

如何製作Der2的子類Der1

+0

無法更改父級。 – Ockonal 2011-04-19 13:24:26

2

使Der2成爲Der1的一個子類,就完成了。

class Base: 
    def Foo(self): 
     pass 

# First derived class 
class Der1(Base): 
    def OwnFoo(self): 
     # Do something 1 
    def OwnFoo2(self): 
     # Do something 2 

    def Foo(self): 
     # Do something 3 

# Second derived class (subclasses Der1) 
class Der2(Der1): 
    pass 

Der2的任何行爲,你想專注可以在類定義中添加。如果在Der2(例如Der2.OwnFoo())中創建了一個名稱相同的新方法,那麼它將重載從Der1繼承的默認方法。

編輯:如果你不能改變父母,把你想要繼承的所有行爲放在基類中,記住你可以重載或定製子類中的任何方法。

在代碼:

# Base class 
class Base: 
    def Foo1(self): 
     # Do something 1 
    def Foo2(self): 
     # Do something 2 
    def Foo(self): 
     # Do something 3 

# First derived class, inherits everything from Base 
class Der1(Base): 
    pass 

# Second derived class 
class Der2(Base): 
    pass 

有一個「絕招」,你可以做調用從父繼承了原有方法,獲取返回的值,然後自定義的行爲。這隻有在方法實際返回一個值時纔會起作用,並且如果該方法操作類中的屬性,那麼該方法可能會很危險,除非這是您想要的和期望的。

在代碼:

# Second derived class, with customized methods 
class Der2(Base): 
    # Anything that is not explicitly define is inherited from parent 
    # as-is. 

    def Foo(self): 
     # My Foo() overloads Base.Foo() inherited from parent class. 
     # Do something "special" 3 

    def Foo1(self): 
     # Calls parent Base.Foo1() and then manipulates return data. 
     base_output = Base.Foo1(self) 
     # Do something "special" 1 with 'base_output' 
+0

看看更新。 – Ockonal 2011-04-19 13:24:09

1

這是一門功課?

看的Der2第一行:

class Der2(Base): 

什麼說什麼是它的父(例如它下降和herits方法和屬性從一個類)?你怎麼能改變這個?

1

如果Der1Der2共享很多代碼,那麼你應該把它放在一個超類;因爲Base不能觸及,在之間引入一類:

class Der(Base): 
    def OwnFoo(self): 
     ... 

class Der1(Der): 
    ... 

class Der2(Der): 
    ... 

(根據您的類層次結構中,「派生Der2Der1」選項,其他人建議也可能是有效的。)