2015-10-29 38 views
0

的目標是:在繼承在Python 3,通過名稱調用一類函數初始化之前具有繼承

  • 乙從A.
  • A和B具有一個工廠方法create,其前調和不同類型的輸入初始化實際的課程。
  • create通過名稱以字符串形式提供不同的創建方法create_general_1,create_general_2,create_specific_b_1

這是我目前的做法:

import sys 

class A: 
    def __init__(self, text): 
     self.text = text 
     print("I got initialized: {}".format(text)) 

    def create(create_method_str): 
     # This is where it breaks: 
     create_method = getattr(sys.modules[__name__], create_method_str) 
     return create_method() 

    def create_general_style_3(): 
     return A("a, #3") 

class B(A): 
    def create_b_style_1(): 
     return B("b, #1") 

if __name__ == "__main__": 
    B.create("create_b_style_1") 

它失敗,出現以下錯誤:

Traceback (most recent call last): File "test.py", line 22, in B.create("create_b_style_1") File "test.py", line 10, in create create_method = getattr(sys.modules[__name__], create_method_str) AttributeError: 'module' object has no attribute 'create_b_style_1'

因此,在某種程度上,我想三件事情結合起來:工廠方法,繼承和按名稱調用函數。 如果某人有更聰明的方法,或者知道如何使這種方法奏效,那將會很棒。

非常感謝!

+1

您在現在的代碼中遇到了一些問題。對於其中一個,您沒有正確定義方法。每個都必須具有'self'或'cls'作爲第一個參數,具體取決於它們是[實例還是類方法](http://stackoverflow.com/q/17134653/2588818)。你可能希望創建一個[靜態方法](http://stackoverflow.com/q/735975/2588818)。您可能還想讓'create'調用子函數,而不用按字符串傳遞它們的名字。這看起來很脆弱,如果僅僅是因爲你可能想在不重新訓練用戶的情況下重新命名這些功能。 –

+0

非常快的回覆,太棒了!我在你的幫助下提出了一個答案。關於脆弱性:在某些時候,用戶輸入將需要映射到內部方法。無論映射發生在何處,這總是會變得脆弱。異常處理可以很容易地集成到當前的解決方案中。如果你知道更好的解決方案,我很高興聽到! – elke

回答

1

感謝雙位鍊金師的評論,我創建了這個解決方案,這似乎工作得很好。任何改進/其他建議不止是歡迎:)

所有的都很好地解釋here

import sys 

class A: 
    def __init__(self, text): 
     self.text = text 
     print("I got initialized: {}".format(text)) 

    @classmethod 
    def create(cls, create_method_str): 
     create_method = getattr(cls, create_method_str) 
     return create_method() 

    @classmethod 
    def create_general_style_3(cls): 
     return cls("a, #3") 

class B(A): 
    @classmethod 
    def create_b_style_1(cls): 
     return cls("b, #1") 

if __name__ == "__main__": 
    B.create("create_b_style_1")