2016-02-05 54 views
0

對於一個有趣的小項目,我創建了以下代碼來實現函數中的非OOP狀態保留。我提出了兩種方法,然後意識到在第二個示例中嵌套inner_fib函數是多餘的(似乎無論如何都正常工作)。我已經測試了所有三個並得到了相同的結果。閉包與功能屬性?

從最佳做法的角度來看,是否比其他人更喜歡? Func屬性更加簡潔,但是我可以看到它們讓以後維護代碼的人感到困惑。這裏是我的例子:

def fib(first=0, second=1, temp=0): 
    first = 0 
    second = 1 
    temp = 0 
    def inner_fib(): 
     nonlocal temp, first, second 
     temp = first + second 
     first = second 
     second = temp 
     return first 
    return inner_fib 


def fib2(): 
    def inner_fib(): 
     inner_fib.temp = inner_fib.first + inner_fib.second 
     inner_fib.first = inner_fib.second 
     inner_fib.second = inner_fib.temp 
     return inner_fib.first 
    return inner_fib 

def inner_fib(): 
    inner_fib.temp = inner_fib.first + inner_fib.second 
    inner_fib.first = inner_fib.second 
    inner_fib.second = inner_fib.temp 
    return inner_fib.first 

res = 0 
a = inner_fib 
a.first = 0 
a.second = 1 
a.temp = 0 
while True: 
    b = a() 
    print(b, res + b) 
    if b % 2 == 0 and b < 4000000: 
     res += b 
    elif res + b > 4000000: 
     break 
print(res) 
+0

現在你爲什麼要這麼做?這是一個可怕的想法。它與使用全局變量的效果相同。 –

+0

因爲我正在學習Mark Lutz的「學習Python」中的函數:)他將閉包和函數屬性作爲輕量級方法來保留狀態信息。 – flybonzai

回答

1

老實說,都不是首選。如你所承認的,第二種方法相當於第三種方法(嵌套是多餘的)。有了第三種方法,您有以下缺點:你添加一些屬性之前

  • inner_fib無效 - 錯誤的潛在來源
  • 你是猴子修補外部對象 - 不良作風和潛在來源的錯誤

第一種方法稍微好一點,但是變異的封閉看起來像是一種矯枉過正。更識別的方式(也與標準庫更兼容)是使用一個發電機:

def fib(first=0, second=1, temp=0): 
    first = 0 
    second = 1 
    temp = 0 

    while True: 
     temp = first + second 
     first = second 
     second = temp 
     yield first 

# in Python 3: 
for _, x in zip(range(5), fib()): 
    print(x) 

一個可變類是一種選擇,這取決於你將如何使用這個功能。