Is there a way to disallow overriding given keyword arguments in a partial? Say I want to create function bar
which always has a
set to 1
. In the following code:
from functools import partial
def foo(a, b):
print(a)
print(b)
bar = partial(foo, a=1)
bar(b=3) # This is fine and prints 1, 3
bar(a=3, b=3) # This prints 3, 3
You can happily call bar
and set a
to 3
. Is it possible to create bar
out of foo
and make sure that calling bar(a=3, b=3)
either raises an error or silently ignores a=3
and keeps using a=1
as in the partial?
This is by design. The documentation for partial
says (emphasize mine):
functools.partial(func, /, *args, **keywords)
Return a new partial object which when called will behave like func called with the positional arguments args and keyword arguments keywords. If more arguments are supplied to the call, they are appended to args. If additional keyword arguments are supplied, they extend and override keywords.
If you do not want that, you can manually reject frozen keyword arguments:
def freeze(f, **kwargs):
frozen = kwargs
def wrapper(*args, **kwargs):
kwargs.update(frozen)
return f(*args, **kwargs)
return wrapper
You can now do:
>>> baz = freeze(foo, a=1)
>>> baz(b=3, a=2)
1
3