2012-02-12 102 views
2

我想將某些函數調用爲單個值並返回集合結果。調用幾個函數並返回集合結果

class Foo: 
    def __init__(self, i): 
     self.i = i 

    def get(self): 
     return self.fn1(self.fn2(self.i)) #200 

    def fn1(self, i): 
     return i + i #10+10 = 20 

    def fn2(self, i): 
     return i * i #20*20 = 200 

    #... 

foo = Foo(10) 
print(foo.get()) 

有沒有更優雅的方式或模式?

+0

不是真的。這有什麼問題? – 2012-02-12 17:13:50

+0

@ S.Lott,只是不好,特別是如果你添加一些更多的方法,如:'self.fn1(self.fn2(self.fn3(self.i)))' – tomas 2012-02-12 17:17:45

+0

我在考慮使用元類。 ..但這對於這麼簡單的事情可能太「瘋狂」了。 – 2012-02-12 17:35:37

回答

2

通常,上面的嵌套函數是在Python中編寫函數的最直接和最可讀的方法。

如果您撰寫許多功能,它可能值得寫compose功能。

def compose(*funcs): 
    if len(funcs) == 1: 
     return funcs[0] 
    else: 
     def composition(*args, **kwargs): 
      return funcs[0](compose(*funcs[1:])(*args, **kwargs)) 
     return composition 

或者,如果你喜歡一個迭代在遞歸解決方案:

def compose_pair(f1, f2): 
    def composition(*args, **kwargs): 
     return f1(f2(*args, **kwargs)) 
    return composition 

def compose_iterative(*funcs): 
    iterfuncs = iter(funcs) 
    comp = next(iterfuncs) 
    for f in iterfuncs: 
     comp = compose_pair(comp, f) 
    return comp 
+0

你是絕對正確的,我的意思是_composition_具有_variable數量的arguments_ – tomas 2012-02-12 18:10:24

3

這是我的嘗試,以改善這一點點。

def fn1(i): 
    return i + i #10+10 = 20 

def fn2(i): 
    return i * i #20*20 = 200 

def get(i): 
    funcs = [fn2, fn1] 
    for f in funcs: 
     i = f(i) 
    return i 

print(get(10)) 
+0

是的,這也是我發生的第一件事。不確定,但裝飾者可能更容易? – tomas 2012-02-12 17:24:22

+1

@tomas:絕對不容易。我想不出一個很好地使用裝飾器的方法。 – 2012-02-12 17:29:49

1

你可以使用一個裝飾風格的解決方案:

class Base() 

    def __init__(self, decorated): 
     self.decorates = decorated 

    def foo(self, arg): 
     if self.decorates: 
      arg = self.decorates.foo(arg) 

     return self._do_foo(arg) 

    def _do_foo(self, arg): 
     return arg 

你實現從基本繼承並實現_do_foo()。 您設置這樣的:

a = Subclass(None) 
b = AnotherSublcass(a) 
c = YetAnotherSubclass(b) 

所有Sublcasses從基地繼承。當你調用c.foo(arg)時,你會得到通過所有三個_do_foo()方法傳遞的結果。

2

就我個人而言,我最喜歡的兩個Python函數是map和reduce。

def get(i): 
    return reduce(lambda acc, f: f(acc), [i,fn2,fn1]) 

def fn1(i): 
    return i + i #10+10 = 20 

def fn2(i): 
    return i * i #20*20 = 200 

print(get(10)) # 200