In the functools.partial example definition, function attributes are used in the returned partial function object:
def partial(func, /, *args, **keywords):
def newfunc(*fargs, **fkeywords):
newkeywords = {**keywords, **fkeywords}
return func(*args, *fargs, **newkeywords)
newfunc.func = func
newfunc.args = args
newfunc.keywords = keywords
return newfunc
What would be the potential problems if those attributes were removed, like below? Shouldn't Python still keep the references to func, args and keywords as long as newfunc is alive?
def partial(func, /, *args, **keywords):
def newfunc(*fargs, **fkeywords):
newkeywords = {**keywords, **fkeywords}
return func(*args, *fargs, **newkeywords)
return newfunc
I know that the actual implementation of functools.partial may be completely different, but what if it were implemented this way, why are the attributes necessary?
Any implementation needs the function and its canned arguments stored somewhere. In your two examples you use a closure. When these partial
implementations return, those values are added to the closure that is returned. In that case, .func
, .args
and .keywords
are redundant. The closure already has them. So, go with option 2.
But python creates a class for this work instead. .func
, .args
and .keywords
are the only copies of the needed data. The class implementation lets you make a partial of a partial in an efficient manner (it combines the arguments of the two partials) and is a bit tidier when building a string display of the object.
But your second closure mechanism is fine, just a different way of doing things.