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?
The *
and **
operators are used in two different situations.
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 .
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.
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.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.