Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to pass through Python args and kwargs?

Tags:

While I have a general understanding (I think) of Python's *args and **kwargs, I'm having trouble understanding how to pass them from one function through to another. Here's my model:

from pdb import set_trace as debug from django.db import models  class Person(models.Model):     name = models.CharField(max_length=30)      def __unicode__(self):         return u'%s' % self.name      def save_name_for(self, *args, **kwargs):         self.name = 'Alex'         return self      def save_name(self, *args, **kwargs):         debug()         self.save_name_for(self, args, kwargs)         self.save() 

I've split saving a name into two functions above. This way I can unit-test the logic I would normally put all in the save_name method by unit-testing the save_name_for method instead.

When I run this in the interpreter and stop in the save_name method, as I would expect, I see this:

(Pdb) args self = args = (1, 2) kwargs = {'last': 'Doe', 'first': 'John'} 

If I then step into the save_name_for method, I see this:

(Pdb) args self = args = (<Person: >, (1, 2), {'last': 'Doe', 'first': 'John'}) kwargs =  

Is there some way to pass the kwargs that are received by the save_name method directly into save_name_for method so that they appear in the latter's kwargs? I'd like to see something like this in save_name_for method's name space:

(Pdb) args self = args = (1, 2) kwargs = {'last': 'Doe', 'first': 'John'}   # <= I want this 

I realize I could parse them in save_name and then pass them explicitly to save_name_for but that seems rather inelegant. I also thought I might do this since args is a tuple...

kwargs = args[2] 

... but it doesn't appear to work. args[2] is just everything (I don't understand this). Is there a Pythonic way to do this?

like image 686
Jim Avatar asked May 19 '14 17:05

Jim


People also ask

How do you pass arguments in Kwargs in Python?

For this problem Python has got a solution called **kwargs , it allows us to pass the variable length of keyword arguments to the function. In the function, we use the double asterisk ** before the parameter name to denote this type of argument.

How do you give Kwargs in Python?

**kwargs allows us to pass a variable number of keyword arguments to a Python function. In the function, we use the double-asterisk ( ** ) before the parameter name to denote this type of argument.

Why we use args and Kwargs in Python?

**kwargs in Python *args enable us to pass the variable number of non-keyword arguments to functions, but we cannot use this to pass keyword arguments. Keyword arguments mean that they contain a key-value pair, like a Python dictionary. **kwargs allows us to pass any number of keyword arguments.

How do you pass an n number argument in Python?

Yes. You can use *args as a non-keyword argument. You will then be able to pass any number of arguments. As you can see, Python will unpack the arguments as a single tuple with all the arguments.


2 Answers

The * and ** operators are used in two different situations.

  1. When used as part of a function definition,

    def save_name_for(self, *args, **kwargs): 

    it is used to signify an arbitrary number of positional or keyword arguments, respectively. The point to remember is that inside the function args will be a tuple, and kwargs will be a dict.

  2. When used as part of a function call,

    args = (1, 2) kwargs = {'last': 'Doe', 'first': 'John'} self.save_name_for(*args, **kwargs) 

    the * and ** act as unpacking operators. args must be an iterable, and kwargs must be dict-like. The items in args will be unpacked and sent to the function as positional arguments, and the key/value pairs in kwargs will be sent to the function as keyword arguments. Thus,

    self.save_name_for(*args, **kwargs) 

    is equivalent to

    self.save_name_for(1, 2, last='Doe', first='John') 

See also the saltycrane blog for an explanation with examples.

like image 190
unutbu Avatar answered Oct 22 '22 09:10

unutbu


You pass them with syntax mirroring the argument syntax:

self.save_name_for(*args, **kwargs) 

Note that you do not need to pass in self; save_name_for is already bound.

like image 45
Martijn Pieters Avatar answered Oct 22 '22 09:10

Martijn Pieters