2017-08-11 32 views
0

我有不同的類,我需要以幾乎相同的方式部分初始化。 init函數接受輸入文件路徑和/或一些numpy數據。以類似的方式初始化不同的類

class InertialData1: 
    def __init__(self, file=None, data=None): 
     # --- this is the (almost) common part --- 
     if file is None: 
     self.file = 'Unknown path to file' 
     else: 
     self.file = file 
     assert isinstance(self.file, str) 

     if data is None: 
     self.data = read_logfile(file, 'a_token') 
     else: 
     self.data = data 
     assert isinstance(self.data, np.ndarray) 
     # --- end of the common part --- 

     # Here other stuff different from class to class 

在read_logfile()函數(外部函數)也從類改變爲類的標記。

class InertialData2: 
    def __init__(self, file=None, data=None): 
     # here the common code as above, but with 'another_token' instead of 'a_token' 
     # here other stuff 
... 

當然,在所有類定義中寫入相同的行是不行的。

可能的解決方案。

我想過定義這樣

def initialize(file, data, token): 
    if file is None: 
     file = 'Unknown path to file' 
    else: 
     file = file 
    assert isinstance(file, str) 

    if data is None: 
     data = read_logfile(file, token) 
    else: 
     data = data 
    assert isinstance(data, np.ndarray) 
return file, data 

外部函數,那麼我可以用它的每個類的初始化方法像這裏面:

class InertialData1: 
    def __init__(self, file=None, data=None): 
     self.file = file 
     self.data = data 
     self.file, self.data = initialize(self.file, self.data, token='a_token') 

這種方式似乎是工作。我只是覺得它不是最好的方法,或者不是pythonic,我希望從你的答案中學到一些東西:) 謝謝

回答

1

你應該能幹(不要重複自己)你的代碼使用類繼承:

class InertialData: 
    def __init__(self, file=None, data=None): 
    # --- this is the common part --- 
    if file is None: 
     self.file = 'Unknown path to file' 
    else: 
     self.file = file 
    assert isinstance(self.file, str) 

    def init_data(self, token, data): 
    if data is None: 
     self.data = read_logfile(self.file, token) 
    else: 
     self.data = data 
    assert isinstance(self.data, np.ndarray) 

class InertialData1(InertialData): 
    def __init__(self, file=None, data=None): 
    # --- this is the different part --- 
    super().__init__(file=file, data=data); 
    self.init_data('token_a', data) 

注意的幾件事情:

你可以做一個「通用」類,InertialData,具有重複功能。然後,所有的自定義類都可以從通用類繼承。請參閱類InertialData1如何將InertialData作爲參數?

在從InertialData繼承所有類,你可以調用super,這將調用父類的,在這種情況下是InertialData__init__方法。

初始化每個類具有不同標記的數據的代碼位已被拉入以令牌作爲參數的函數中。現在,您可以撥打initialize_data('token_a')中的任何繼承自InertialData的任何類的__init__函數。

我將您的類重命名爲以大寫字母開頭(正如Python的慣例)。

+0

感謝您的回覆。但它似乎並沒有像這樣工作。 類型錯誤:超級不採取關鍵字參數 – Robyc

+0

對不起,我忘了'super'自動重用那些在傳遞的參數我也意識到,您將需要通過'data'到'init_data'方法,所以我加了。那個代碼太 –

+0

'超'獨自也是行不通的。 'super().__ init __(file,data)'正在工作。 但是,我不確定如何調用基本初始化函數是一種很好的做法。 – Robyc