2017-05-24 25 views
0

繼承給init考慮類如何避免重複調用傳遞一個子類時在python

class Grid(): 
    def __init__(self,r,z,t): 
     self.rgrid = r 
     self.zgrid = z 
     self.tgrid = t 
     self.otherstuff = long_computation(r,t,z) 

class Solution(Grid): 
    def __init__(self,r,g): 
     self.zones = r 
     Grid.__init__(self,g.r,g.z,g.t) 

g = Grid(my_r,my_z,my_t) 
sol = Solution(r,g) 

這造成我想要的東西,除了「long_computation」做了兩次。無論我是否只是調用Grid,或者我是否也執行了解決方案步驟,什麼樣的結構化類都可以起作用?

感謝,J.

+2

爲什麼'Solution'從'Grid'繼承,爲什麼它利用現有的'Grid'作爲參數,而不是'r','z'和't'? – user2357112

+0

'Grid .__ init__'和'Solution .__ init__'中的'r'有什麼區別?看起來最後一個應該命名爲'zones' –

+0

你可以有一個類變量'done_long_computation',它會在你第一次設置__init__'時執行,'__init__'檢查是否設置了'done_long_computation'。 – boardrider

回答

0

快速,骯髒的方式將是一個 「新」 參數添加到初始化:

def long_computation(r, t, z): 
    print "Oh, the despair of wasted time!", r, t, z 

class Grid(): 
    def __init__(self,r,z,t, new_grid=True): 
     self.rgrid = r 
     self.zgrid = z 
     self.tgrid = t 
     if new_grid: 
      self.otherstuff = long_computation(r,t,z) 

class Solution(Grid): 
    def __init__(self,r,g): 
     self.zones = r 
     Grid.__init__(self, g.rgrid, g.zgrid, g.tgrid, False) 
     # Inherit long computation from parent. 
     self.otherstuff = g.otherstuff 

my_r = 77 
my_z = 18 
my_t = 6.2 
r = 0.333 

g = Grid(my_r,my_z,my_t) 
sol = Solution(r,g) 

另一種可能性是memoize的longcomputation

這有幫助嗎?我知道這並不美觀,但它完成了工作。

1

你可以有一個方法來在父類中執行計算。使用這個,你可以調用這個方法並且計算需要很長時間來計算的東西。

class Grid(): 
    def __init__(self,r,z,t): 
     self.rgrid = r 
     self.zgrid = z 
     self.tgrid = t 

    def start_long_computation(self): 
     self.otherstuff = long_computation(self.rgrid,self.tgrid,self.zgrid) 

呼叫解決方案實例start_long_computation

class Solution(Grid): 
    def __init__(self,r,my_r ,my_z ,my_t): 
     self.zones = r 
     Grid.__init__(self, my_r ,my_z ,my_t) 
     Grid.start_long_computation(self) 

您現在可以訪問otherstuff在解決方案實例使用self.otherstuff

class Grid(): 
    def __init__(self,r,z,t): 
     self.rgrid = r 
     self.zgrid = z 
     self.tgrid = t 

    def start_long_computation(self): 
     return long_computation(self.rgrid,self.tgrid,self.zgrid) 

class Solution(): 
    def __init__(self,r,g): 
     self.zones = r 
     self.otherstuff = g.start_long_computation() 

g = Grid(my_r,my_z,my_t) 
sol = Solution(r,g) 
+0

嗨,有沒有辦法解決方案知道如果otherstuff已經創建?有時候我會希望使用Grid並讓它運行長計算而不將它作爲Solution的一部分調用。有時我會想調用Grid而不調用Solution。也許子類()...嗯。我剛剛看到__dict __。keys() – Tunneller

+0

您可以使用self .__ dict__來查看該類的屬性是否存在,並在必要時進行計算。 – Harwee

0

嗯,這看起來很醜陋,但建立在上面:

class Grid(object): 
    def __init__(self,r,z,t):  
     self.rgrid = r 
     self.zgrid = z 
     self.tgrid = t  

     if "otherstuff" not in self.__dict__.keys(): 
      self.otherstuff = self.long_computation(r,t,z) 
     else: 
      print "No Need to Call" 

    def long_computation(ggg,r, t, z): 
     return 123456 

class Solution(Grid): 
    def __init__(self,r,g): 
     self.zones = r 

    if "otherstuff" in g.__dict__.keys(): 
     self.otherstuff = g.otherstuff 

    super(Solution, self).__init__(g.rgrid,g.zgrid,g.tgrid) 
1
  • IMO你應該避免__init__內的任何計算和只做屬性分配,所以如果你想要做long_computation一次,並使用它的結果,你可以做到這一點的__init__外,並通過作爲參數。

  • 如果你不使用Python的你應該繼承你的基類Gridobject類型(Python 3中所有的類都是從objectby default繼承)。並且有函數superprobably should use it,如super(Solution, self).__init__(或只是super().__init__Python 3)而不是編寫Grid.__init__

  • 傳遞Grid實例初始化Solution對象看起來很醜,爲什麼不傳遞所需的Grid屬性?你的例子也不會工作,因爲Grid對象沒有r,z,t字段,但是rgrid,zgrid,tgrid。如果需要從Grid構造Solution實例,則可以編寫自定義構造函數(例如,其中有許多類型爲datetime.datetime類型)。

考慮到這一切的言論

class Grid(object): 
    def __init__(self, r, t, z, otherstuff): 
     self.rgrid = r 
     self.tgrid = t 
     self.zgrid = z 
     self.otherstuff = otherstuff 


class Solution(Grid): 
    def __init__(self, zones, r, t, z, otherstuff): 
     self.zones = zones 
     super(Solution, self).__init__(r, t, z, otherstuff) 

    @classmethod 
    def from_grid(cls, zones, grid): 
     return cls(zones, grid.rgrid, grid.tgrid, grid.zgrid, grid.otherstuff) 


otherstuff = long_computation(my_r, my_t, my_z) 
g = Grid(my_r, my_t, my_z, otherstuff) 
sol = Solution.from_grid(r, g) 
+0

謝謝,我指着super()......然後發現舊式課程與新課程的奧祕。 classmethod設備對我來說也是新的,並且會很有用。更詳細地說,我的「otherstuff」更像是二十幾個值:grid.o1,grid.o2,grid.o3,grid.o4,grid.o5,.....等等。我不想擁有每次輸入主代碼中的所有內容。但是我可以使用classmethod來保持主代碼的清潔。欣賞更新。 – Tunneller