0

I am trying to wrap my head around decorators. So I tried passing arguments to a decorator and processing them inside the decorator function. I just pass a list to the decorator and want my list to be processed inside the decorator function after calling the original function. Here's my code

def decorator_function(original_function):
    def new_function(*args, **kwargs):
        print("Your list shall be processed now.")
        print args
        #Do something with the passed list here.Say, call a function Process(list,string)
        original_function(*args, **kwargs) 
    return new_function



@decorator_function([1,2,3])
def hello(name = None):
    if name == None:
        print "You are nameless?"
    else:
        print "hello there,",name

hello("Mellow")

I get this error

Your list shall be processed now.
(<function hello at 0x7f9164655758>,)
Traceback (most recent call last):
  File "anno_game.py", line 14, in <module>
    def hello(name = None):
  File "anno_game.py", line 8, in new_function
    original_function(*args, **kwargs) 
TypeError: 'list' object is not callable

Can anyone please tell me what have I messed up here and point me in the right direction?

vaultah
  • 44,105
  • 12
  • 114
  • 143
Tania
  • 1,855
  • 1
  • 15
  • 38
  • 2
    I would also highly recommend taking a look at the e-satis answer to http://stackoverflow.com/questions/739654/how-can-i-make-a-chain-of-function-decorators-in-python, which has one of the best, most understandable explanations of decorators I've read to date, including decorators that accept arguments. – lemonhead Jun 17 '15 at 07:49

1 Answers1

1
def decorator_function(original_function):
    def new_function(*args, **kwargs):
        print("Your list shall be processed now.")
        print args
        #Do something with the passed list here.Say, call a function Process(list,string)
        original_function(*args, **kwargs) 
    return new_function

@decorator_function([1,2,3])
def hello(name = None):
    if name == None:
        print "You are nameless?"
    else:
        print "hello there,",name

hello("Mellow")

When you do @decorator_function([1,2,3]) decorator_function is called with [1,2,3] passed to it as original_function argument, which you are trying to call original_function(*args, **kwargs).

To have the decorator to receive a list, you need to make another wrapper:

def decorator_function(a_list):

        print("Your list shall be processed now.", a_list)
        #Do something with the passed list here.Say, call a function Process(a_list)

    def wrapper(original_function):

        def new_function(*args, **kwargs):

            print("Your list with function args shall be processed now.", a_list, args)
            #Do something with the passed list here.  Say, call a function Process(a_list, args)

            original_function(*args, **kwargs) 

        return new_function

    return wrapper
warvariuc
  • 57,116
  • 41
  • 173
  • 227
  • But When I tried this code, the wrapper print statement is not getting printed. `print("Your list with function args shall be processed now.", a_list, args) #Do something with the passed list here. Say, call a function Process(a_list, args) original_function(*args, **kwargs) ` – Tania Jun 17 '15 at 08:43
  • Oh my mistake. I forgot to call the original function, Sorry. Thanks for the answer :) Works like a charm – Tania Jun 17 '15 at 08:45