0

I have an addition function with two parameters a and b which simply adds a and b. To round this number, I have made a decorator factory which takes a decimals parameter and round the results of the addition function to the specified number of decimals. However, this requires the decimals number to be set at function definition. I am looking for a more dynamic approach.

Is it instead possible to make the decorator alter the addition function, such that the addition function gets a new parameter "decimals"? Here is my code:

import functools


def rounding(decimals):
    def decorator(func):
        @functools.wraps(func)
        def wrapper(*args, **kwargs):
            return round(func(*args, **kwargs), decimals)
        return wrapper
    return decorator


@rounding(decimals=2)
def addition(a: float, b: float):
    return a + b

addition(a=1.0003, b=2.01)

So this makes the addition function always round to 2 decimals. What I instead want my decorator to do, is add a new arguments, such that I can call

addition(a=1.0003, b=2.01, decimals=2)

Is there a way to do this and if yes, is there a way to do this such that function docs still shows a, b and decimals instead of *args, **kwargs (for example when pressing ctrl+P in pycharm on the function)

I have just started working my way around python decorators. I have used https://realpython.com/primer-on-python-decorators/ as inspiration. I have not been able to find an existing answer on this site. The nearest I got was related to partial functions like here, but perhaps I am just searching for the wrong thing.

I am using Python 3.10.

RVA92
  • 666
  • 4
  • 17
  • Does this answer your question? [Decorating a function to add custom arguments to function](https://stackoverflow.com/questions/18731612/decorating-a-function-to-add-custom-arguments-to-function) – mkrieger1 May 27 '22 at 13:51

1 Answers1

0

You've made it too complicated.

  1. You don't want a decorator which takes arguments, so you need only 2 levels of nested functions.

  2. Simply add the decimals parameter to the function returned by the decorator.

def rounding():
    @functools.wraps(func)
    def wrapper(a, b, decimals):
        return round(func(a, b), decimals)
    return wrapper
mkrieger1
  • 19,194
  • 5
  • 54
  • 65
  • Thank you, that may be part of the solution. I would like to use this decorator on other functions as well which have other parameters. Is there a way to dynamically do this. E.g. If I want to use the same decorator on a function with parameters x, Z and y instead og a and b? – RVA92 May 27 '22 at 13:49