0

How does one use a decorator to return a given function with all of its arguments modified if the number of arguments is arbitrarily long? I'm tasked with capitalizing all arguments in an input function to a decorator and I can't figure out how to pass an infinite amount of new arguments back into the function.

I'm trying this in theory:

def allCaps(func):  
    def ret(*args):  
        return func(*args.upper())
    return ret  

but you can't mod a tuple so it doesn't work correctly

Nate127
  • 3
  • 2

2 Answers2

1

something like:

def allCaps(func):
    def wrapper(*args, **kwargs):
        if not all(isinstance(arg,str) for arg in args):
            # use isinstance(basestr, arg) for arg in args in python2
            raise TypeError("Wrong argument type")
        else:
            return func(*[arg.upper() for arg in args], **kwargs)
    return wrapper

@allCaps
def this_function_needs_allcaps(*args, **kwargs):
    print("These are my arguments!")
    for arg in args:
        print(arg)
Adam Smith
  • 52,157
  • 12
  • 73
  • 112
0

You'll want to build a new list (it could be a tuple as well; the Python * syntax just expects an iterable) with the arguments, as follows:

new_args = [arg.upper() for arg in args]
return func(*new_args)
rmunn
  • 34,942
  • 10
  • 74
  • 105
  • oh so you can use the * function on other lists...makes sense. Thank you! – Nate127 Jul 28 '14 at 06:22
  • @Nate127 - Yes, and you can use the ** syntax on any dictionary as well: either the kwargs dictionary that you got from the `def myfn(*args, **kwargs)` declaration, or a new dictionary that you built up by hand. It's a very handy tool to know about. – rmunn Jul 28 '14 at 06:24
  • Also, if you're unfamiliar with list comprehensions, [this is a pretty good introduction](http://www.pythonforbeginners.com/lists/list-comprehensions-in-python/). You may know this already, but just in case, I figured I'd give you the link. – rmunn Jul 28 '14 at 06:29
  • I learned comprehensions a while back.. it's the "*" function I was never really taught. Makes sense to get iterable arguments all at once instead of putting them in an unusable tuple. – Nate127 Jul 28 '14 at 06:31
  • 1
    @Nate127 [here's the question for you then!](http://stackoverflow.com/questions/36901/what-does-double-star-and-star-do-for-python-parameters) – Adam Smith Jul 28 '14 at 06:32