Reputation: 3931
For a fun little project I created the following code to practice non-OOP state-retention in functions. I came up with two ways of doing it, and then realized that nesting the inner_fib
function in the second example was redundant (seems to function just fine regardless). I have tested all three and gotten the same result.
From a best practice point of view, is one preferred over the other? Func attributes are more concise, but I can see them being confusing to someone maintaining your code later. Here are my examples:
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)
Upvotes: 1
Views: 97
Reputation: 9726
Honestly, neither is preferred. As you admit, the second approach is equivalent to the third one (the nesting is redundant). With the third approach, you have the following disadvantages:
inner_fib
is not valid before you add some attributes to it — potential source of errorsThe first approach is slightly better, but a mutating closure seems like an overkill. A more recognizable way (and also more compatible with the standard library) would be to use a generator:
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)
A mutable class is an alternative, depending on how you are going to use this function.
Upvotes: 2