s = [0.55, 0.25, 0.53, 0.45, 0.55] # s[i] = s[i]–a∙s[i–1] def pre_process(a): def _decorator(func): def _wrapper(*args, **kwargs): arg = [args[i]+1 for i in range(len(args))] # s[i] = s[i]–a∙s[i–1] return func(arg) return _wrapper return _decorator @pre_process(a=0.93) def plot_signal(s): for sample in s: print(sample) plot_signal(s) 

On line 11 (arg = [args [i] +1 ...) an error occurs: "can only concatenate list (not" int ") to list"

    1 answer 1

    When you pass the list s to plot_signal() , then the following will fall into the args inside the decorator: ([0.55, 0.25, 0.53, 0.45, 0.55],) , i.e. in fact, s is the first element of the args parameter set. Therefore, args[0]+1 equivalent to [0.55, 0.25, 0.53, 0.45, 0.55] + 1 , which is what the interpreter curses.

    There are two solutions:

    - pass s through an asterisk (then the function itself must be changed accordingly): plot_signal(*s)
    - inside the decorator select the first element (s), and then separately *args and **kwargs :

     def _wrapper(s, *args, **kwargs): s = [s[i]+1 for i in range(len(s))] return func(s, *args, **kwargs) 
    • There is no need to convert args to the list, this is already a tuple, you can refer to the index: s = args[0] - Timofei Bondarev
    • @TimofeyBondarev, converted to the list, because for tuple it is impossible to make args[0] = s - insolor
    • You can do this: s, *other = args; ...; return func(s, *other, **kwargs) s, *other = args; ...; return func(s, *other, **kwargs) s, *other = args; ...; return func(s, *other, **kwargs) - Timofei Bondarev
    • @TimofeyBondarev, you can even easier) changed the answer - insolor