With explicit referencing
A clean way to do this is probably using iterable unpacking and a mapping, like:
def foo(a,b,c):
a,b,c = map(lambda x:x+1,(a,b,c))
# ...
Or for rounding:
def foo(a,b,c):
a,b,c = map(round,(a,b,c))
# ...
Since this is still explicit, and furthermore keeps the parameters in the function signature of foo.
You can of course use *args and **kwargs and manipulate these (directly), but that could result in losing information about what the parameters a, b and c mean (their semantics).
Using a decorator (apply the function on all parameters)
Another way to do it, that will remove the semantics of the parameters is using a decorator:
def apply_func_args(func):
def dec(f):
def g(*args,**kwargs):
return f(*map(func,args),**{k:func(v) for k,v in kwargs.items()})
g.__name__ = f.__name__
g.__doc__ = f.__doc__
return g
return dec
Then you can put the decorator on foo, like:
@apply_func_args(round)
def foo(a,b,c):
# ...
Now if you call foo(1.4,1.3,1.9), foo will obtain (a,b,c) == (1,1,2). For example, if you want to print a, b, and c:
>>> def apply_func_args(func):
... def dec(f):
... def g(*args,**kwargs):
... return f(*map(func,args),**{k:func(v) for k,v in kwargs.items()})
... g.__name__ = f.__name__
... g.__doc__ = f.__doc__
... return g
... return dec
...
>>> @apply_func_args(round)
... def foo(a,b,c):
... print((a,b,c))
...
>>> foo(1.4,1.3,1.9)
(1, 1, 2)
>>> foo(1.4,2.5,c=0)
(1, 2, 0)
>>> foo(b=1.4,a=2.5,c=0)
(2, 1, 0)
So here we defined a clean way to apply the function (round) on all named and unnamed parameters of foo. As a result, if we call foo, foo will always obtain rounded values.
foosince I have no control over that codebase.