Python convert args to kwargs

Python convert args to kwargs

Note — co_varnames will include local variables as well as keywords. This probably won’t matter, as zip truncates the shorter sequence, but may result in confusing error messages if you pass the wrong number of args.

You can avoid this with func_code.co_varnames[:func_code.co_argcount] , but better is to use the inspect module. ie:

import inspect argnames, varargs, kwargs, defaults = inspect.getargspec(func) 

You may also want to handle the case where the function defines **kwargs or *args (even if just to raise an exception when used with the decorator). If these are set, the second and third result from getargspec will return their variable name, otherwise they will be None.

Solution 2

Any arg that was passed positionally will be passed to *args. And any arg passed as a keyword will be passed to **kwargs. If you have positional args values and names then you can do:

kwargs.update(dict(zip(myfunc.func_code.co_varnames, args))) 

to convert them all into keyword args.

Solution 3

If you’re using Python >= 2.7 inspect.getcallargs() does this for you out of the box. You’d just pass it the decorated function as the first argument, and then the rest of the arguments exactly as you plan to call it. Example:

>>> def f(p1, p2, k1=None, k2=None, **kwargs): . pass >>> from inspect import getcallargs 

I’m planning to do f(‘p1’, ‘p2’, ‘p3′, k2=’k2′, extra=’kx1’) (note that k1 is being passed positionally as p3), so.

>>> call_args = getcallargs(f, 'p1', 'p2', 'p3', k2='k2', extra='kx1') >>> call_args > 

If you know the decorated function won’t use **kwargs , then that key won’t appear in the dict, and you’re done (and I’m assuming there’s no *args , since that would break the requirement that everything have a name). If you do have **kwargs , as I have in this example, and want to include them with the rest of the named arguments, it takes one more line:

>>> call_args.update(call_args.pop('kwargs')) >>> call_args

Update: for Python >= 3.3, see inspect.Signature.bind() and the related inspect.signature function for functionality similar to (but more robust than) inspect.getcallargs() .

Solution 4

Well, this may be overkill. I wrote it for the dectools package (on PyPi), so you can get updates there. It returns the dictionary taking into account positional, keyword, and default arguments. There is a test suite in the package (test_dict_as_called.py):

def _dict_as_called(function, args, kwargs): """ return a dict of all the args and kwargs as the keywords they would be received in a real function call. It does not call function. """ names, args_name, kwargs_name, defaults = inspect.getargspec(function) # assign basic args params = <> if args_name: basic_arg_count = len(names) params.update(zip(names[:], args)) # zip stops at shorter sequence params[args_name] = args[basic_arg_count:] else: params.update(zip(names, args)) # assign kwargs given if kwargs_name: params[kwargs_name] = <> for kw, value in kwargs.iteritems(): if kw in names: params[kw] = value else: params[kwargs_name][kw] = value else: params.update(kwargs) # assign defaults if defaults: for pos, value in enumerate(defaults): if names[-len(defaults) + pos] not in params: params[names[-len(defaults) + pos]] = value # check we did it correctly. Each param and only params are set assert set(params.iterkeys()) == (set(names)|set([args_name])|set([kwargs_name]) )-set([None]) return params 

Solution 5

Nadia’s answer is correct, but I feel like a working demo of that answer is useful.

def decorator(func): def wrapped_func(*args, **kwargs): kwargs.update(zip(func.__code__.co_varnames, args)) print(kwargs) return func(**kwargs) return wrapped_func @decorator def thing(a,b): return a+b 

Given this decorated function, the following calls return the appropriate answer:

thing(1, 2) # prints returns 3 thing(1, b=2) # prints returns 3 thing(a=1, b=2) # prints returns 3 

Note however that things start getting weird if you start nesting decorators because the decorated function now no longer takes a and b, it takes args and kwargs:

@decorator @decorator def thing(a,b): return a+b 

Here thing(1,2) will print and error with TypeError: thing() got an unexpected keyword argument ‘args’

Источник

Python convert args to kwargs

Any arg that was passed positionally will be passed to *args. And any arg passed as a keyword will be passed to **kwargs. If you have positional args values and names then you can do:,But I can’t figure out how to tell what was passed in positionally and what was as keyword.,to convert them all into keyword args.,I’m planning to do f(‘p1’, ‘p2’, ‘p3′, k2=’k2′, extra=’kx1’) (note that k1 is being passed positionally as p3), so.

Any arg that was passed positionally will be passed to *args. And any arg passed as a keyword will be passed to **kwargs. If you have positional args values and names then you can do:

kwargs.update(dict(zip(myfunc.func_code.co_varnames, args))) 

Answer by Isabel Lu

This example is a little more complicated, as you can see on line 3. We use .items() to iterate over a dictionary, tuple() to convert the dictionary to a tuple so that we can use [0] to pull the first element of the tuple. All of this packs the key-value pair into k and v .,Notice that the return statement in merge_two_dictionaries is wrapped in curly brackets. This ensures our function returns a dictionary.,The double asterisk allows us to make some otherwise complex dictionary processes occur quite elegantly. For example, we can use the double-asterisk to merge two uniquely keyed dictionaries.,Let’s use this same unpacking pattern on a dictionary.

In this gist, we have the tuple, t , being unpacked into three variables; a , b and c . When we print these vars, we will see the individual elements of the tuple.

When k and v are printed, we see:

We use the same pattern of unpacking by setting three variables equal to a list. However, here we add the packing operator to the variable b . Can you guess what the print statements will look like?

Answer by Easton Beck

>>> def argsKwargs(*args, **kwargs): . print(args) . print(kwargs) . >>> argsKwargs('1', 1, 'slgotting.com', upvote='yes', is_true=True, test=1, sufficient_example=True) ('1', 1, 'slgotting.com')

Answer by Martha Watts

I am writing a decorator that needs to call other functions prior to call of the function that it is decorating. The decorated function may have positional arguments, but the functions the decorator will call can only accept keyword arguments. Does anyone have a handy way of converting positional arguments into keyword arguments?,Given this decorated function, the following calls return the appropriate answer:,to convert them all into keyword args.,I know that I can get a list of the variable names of the decorated function:

I know that I can get a list of the variable names of the decorated function:

>>> def a(one, two=2): . pass >>> a.func_code.co_varnames ('one', 'two') 

My decorator looks like this:

class mydec(object): def __init__(self, f, *args, **kwargs): self.f = f def __call__(self, *args, **kwargs): hozer(**kwargs) self.f(*args, **kwargs) 

Answer by Ben Dunn

Python passes variable length non keyword argument to function using *args but we cannot use this to pass keyword argument. For this problem Python has got a solution called **kwargs, it allows us to pass the variable length of keyword arguments to the function.,As in the above example we are not sure about the number of arguments that can be passed to a function. Python has *args which allow us to pass the variable number of non keyword arguments to function.,*args passes variable number of non-keyworded arguments list and on which operation of the list can be performed.,**kwargs passes variable number of keyword arguments dictionary to function on which operation of a dictionary can be performed.

Example 1: Function to add 3 numbers

def adder(x,y,z): print("sum:",x+y+z) adder(10,12,13)

When we run the above program, the output will be

Lets see what happens when we pass more than 3 arguments in the adder() function.

def adder(x,y,z): print("sum:",x+y+z) adder(5,10,15,20,25)

When we run the above program, the output will be

TypeError: adder() takes 3 positional arguments but 5 were given

Example 2: Using *args to pass the variable length arguments to the function

def adder(*num): sum = 0 for n in num: sum = sum + n print("Sum:",sum) adder(3,5) adder(4,5,6,7) adder(1,2,3,5,6)

When we run the above program, the output will be

Example 3: Using **kwargs to pass the variable keyword arguments to the function

def intro(**data): print("\nData type of argument:",type(data)) for key, value in data.items(): print("<> is <>".format(key,value)) intro(Firstname="Sita", Lastname="Sharma", Age=22, Phone=1234567890) intro(Firstname="John", Lastname="Wood", Email="[email protected]", Country="Wakanda", Age=25, Phone=9876543210)

When we run the above program, the output will be

Data type of argument: Firstname is Sita Lastname is Sharma Age is 22 Phone is 1234567890 Data type of argument: Firstname is John Lastname is Wood Email is john[email protected] Country is Wakanda Age is 25 Phone is 9876543210

Answer by Maximo Benton

We can use the special syntax of *args and **kwargs within a function definition in order to pass a variable number of arguments to the function. ,First, let’s print out the **kwargs arguments that we pass to a function. We’ll create a short function to do this:,And, when working with positional parameters along with named keyword parameters in addition to *args and **kwargs, your function would look like this:,Because we used *args to send a variable-length argument list to our function, we were able to pass in as many arguments as we wished into the function calls.

def multiply(x, y): print (x * y) 
def multiply(x, y): print (x * y) multiply(5, 4) 

Now, we can run the above code:

We’ll receive the following output, showing that the integers 5 and 4 were multiplied as per the multiply(x,y) function:

def multiply(x, y): print (x * y) multiply(5, 4, 3) 
def multiply(x, y): print (x * y) multiply(5, 4, 3) 
OutputTypeError: multiply() takes 2 positional arguments but 3 were given 
def multiply(*args): z = 1 for num in args: z *= num print(z) multiply(4, 5) multiply(10, 9) multiply(2, 3, 4) multiply(3, 5, 10, 6) 

When we run this code, we’ll receive the product for each of these function calls:

def print_kwargs(**kwargs): print(kwargs) 
def print_kwargs(**kwargs): print(kwargs) print_kwargs(kwargs_1="Shark", kwargs_2=4.5, kwargs_3=True) 

Let’s run the program above and look at the output:

def print_values(**kwargs): for key, value in kwargs.items(): print("The value of <> is <>".format(key, value)) print_values(my_name="Sammy", your_name="Casey") 

We can now run the program and look at the output:

OutputThe value of your_name is Casey The value of my_name is Sammy 
def print_values(**kwargs): for key, value in kwargs.items(): print("The value of <> is <>".format(key, value)) print_values( name_1="Alex", name_2="Gray", name_3="Harper", name_4="Phoenix", name_5="Remy", name_6="Val" ) 

When we run the program at this point, we’ll receive the following output, which may again be unordered:

OutputThe value of name_2 is Gray The value of name_6 is Val The value of name_4 is Phoenix The value of name_5 is Remy The value of name_3 is Harper The value of name_1 is Alex 

In practice, when working with explicit positional parameters along with *args and **kwargs , your function would look like this:

def example(arg_1, arg_2, *args, **kwargs): . 

And, when working with positional parameters along with named keyword parameters in addition to *args and **kwargs , your function would look like this:

def example2(arg_1, arg_2, *args, kw_1="shark", kw_2="blobfish", **kwargs): . 
def some_args(arg_1, arg_2, arg_3): print("arg_1:", arg_1) print("arg_2:", arg_2) print("arg_3:", arg_3) args = ("Sammy", "Casey", "Alex") some_args(*args) 

When we run the program with the python some_args.py command, we’ll receive the following output:

Outputarg_1: Sammy arg_2: Casey arg_3: Alex 
def some_args(arg_1, arg_2, arg_3): print("arg_1:", arg_1) print("arg_2:", arg_2) print("arg_3:", arg_3) my_list = [2, 3] some_args(1, *my_list) 

If we run the program above, it will produce the following output:

Outputarg_1: 1 arg_2: 2 arg_3: 3 
def some_kwargs(kwarg_1, kwarg_2, kwarg_3): print("kwarg_1:", kwarg_1) print("kwarg_2:", kwarg_2) print("kwarg_3:", kwarg_3) kwargs = some_kwargs(**kwargs) 

Let’s run the program above with the python some_kwargs.py command:

Outputkwarg_1: Val kwarg_2: Harper kwarg_3: Remy 

Answer by Galilea Austin

*args and **kwargs in Python,The syntax is to use the symbol * to take in a variable number of arguments; by convention, it is often used with the word args.,In Python, we can pass a variable number of arguments to a function using special symbols. There are two special symbols:,The special syntax *args in function definitions in python is used to pass a variable number of arguments to a function. It is used to pass a non-key worded, variable-length argument list.

Источник

Читайте также:  Php удалить символы после
Оцените статью