2015-11-03 72 views
0

我在想如果下面的策略是在方法中創建動態函數的合適/ pythonic方法。我們的目標是讓一個類可以基於由FUN()定義的複雜模型來計算值,但是我希望能夠在腳本中更改該模型而不重寫它,或者創建一堆不同類的類(因爲這函數是我期望改變的唯一的東西)。創建動態類方法的Python方法

我也讀過對這個question的迴應,我有它結構的方式可能最終會變慢?我打算打電話setupFunction() 1到3次模擬(改變模型)並呼籲FUN幾千次。

僞...

class MyClass: 

    def __init__(self, model = 'A'): 
    self.setupFunction(model) 
    # Other Class Stuff... 

    def setupFunction(self, _model): 
    if _model == 'A': 
     def myFunc(x): 
     # Do something with x, store in result 
     return result 
    else: 
     def myFunc(x): 
     # Do something different with x 
     return result 
    self.FUN = myFunc 

    # Other Class Methods... some of which may call upon self.FUN 


Model1 = MyClass('A') 
Model2 = MyClass('B') 
print(Model1.FUN(10)) 
print(Model2.FUN(10)) 

我已經做了一些小的測試和上面的好像是在第一眼就不會打破。我知道我還可以做的做,而不是下面類似的東西,但隨後將要測試的每個呼叫的模式FUN(),我會在年底有很多不同的典型案例:

class MyClass(): 

    def __init__(self, model = 'A'): 

    def FUN(self, x): 
    if self.model == 'A': 
     # result = Stuff 
    else: 
     # result = Other Stuff 
    return result 

還是新蟒蛇,所以謝謝任何反饋!

+2

當然,這是好的。函數和擴展方法是第一類對象,因此您可以動態地將它們分配給您的內容。這取決於您是否使您的代碼更易於維護或更令人困惑。但從表面上看,這很好。 – RobertB

+1

我投票結束這個問題,因爲它應該在Stack Exchange Code Review站點上。 –

回答

1

不知道我是否理解你的問題... 這樣的事情呢?

class MyClass(): 

    model_func = {'A' : funca, 'B' : funcb} 

    def __init__(self, model): 
     self.func = self.model_func[model] 

    def funca(): 
     pass 

    def funcb(): 
     pass 

a = MyClass('A') 
a.func() 

b = MyClass('B') 
b.func() 

其他選項可能是這樣的(關注更好的分離):

class Base(object): 

    def __new__(cls, category, *arguments, **keywords): 
     for subclass in Base.__subclasses__(): 
      if subclass.category == category: 
       return super(cls, subclass).__new__(subclass, *arguments, **keywords) 
     raise Exception, 'Category not supported!' 

class ChildA(Base): 
    category = 'A' 

    def __init__(self, *arguments, **keywords): 
     print 'Init for Category A', arguments, keywords 

    def func(self): 
     print 'func for Category A' 


class ChildB(Base): 
    category = 'B' 

    def func(self): 
     print 'func for Category B' 

if __name__ == '__main__': 
    a = Base('A') 
    a.func() 
    print type(a) 
    b = Base('B') 
    b.func() 
    print type(b) 
+0

我認爲這將最終成爲最佳解決方案。謝謝! – Oniow

+0

'NameError:name'funca'is not defined': -/ – abukaj

+0

只反轉'funca'和'funcb'的順序。將主題放在'model_func = {'A':funca,'B':funcb}'之前。 – RicLeal

1

您可以使用__new__,返回不同的子類:

class MyClass(): 
    def __new__(self, model): 
     cls = {'A': ClassA, 'B': ClassB}[model] 
     return object.__new__(cls) 

class ClassA(MyClass): 
    def func(): 
     print("This is ClassA.func") 

class ClassB(MyClass): 
    def func(): 
     print("This is ClassB.func") 

a = MyClass('A') 
a.func() 

b = MyClass('B') 
b.func() 
+0

感謝您的回覆! – Oniow