Note: I'm asking if there's One Pythonic Way to do this (using default args seems less Pythonic than using partial) and if there are significant limitations to either method (the "cost" - I wouldn't expect timing to differ significantly but perhaps there are other limitations I'm not seeing that tilt the balance towards one methodology versus the other).
I'm trying to understand the costs of using 'partial' in late-binding situations where a lambda is not feasible. I've created some example code based on this guide to exemplify this.
The following doesn't work as intended due to late binding:
def create_thingies():
thingies = []
for i in range(1,6):
def thingy(x):
print("Some output", i)
return i ** (x * i)
thingies.append(thingy)
return thingies
results=[]
for thingy in create_thingies():
results.append(thingy(2))
print(results)
Output:
Some output 5
Some output 5
Some output 5
Some output 5
Some output 5
[9765625, 9765625, 9765625, 9765625, 9765625]
Using 'partial' we avoid that problem, but at what cost?
from functools import partial
def create_thingies():
thingies = []
for i in range(1,6):
def thingy(i, x):
print("Some output", i)
return i ** (x * i)
thingies.append(partial(thingy, i))
return thingies
results=[]
for thingy in create_thingies():
results.append(thingy(2))
print(results)
Output:
Some output 1
Some output 2
Some output 3
Some output 4
Some output 5
[1, 16, 729, 65536, 9765625]
I've seen much discussion about lambda vs partial here, but in cases where a lambda wouldn't work well (a very complex function) if at all (function with more than expressions) is partial the way to go or is there a better way short of coercing this into a lambda expression?