虽然我对Python的*args和**kwargs有一般的了解(我认为),但我很难理解如何将它们从一个函数传递到另一个函数.这是我的模特:
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()
Run Code Online (Sandbox Code Playgroud)
我将名称分成两个以上的函数.这样我就可以通过对save_name_for方法进行单元测试来对我通常将所有逻辑进行单元测试.
当我在解释器中运行它并在save_name方法中停止时,正如我所料,我看到:
(Pdb) args
self =
args = (1, 2)
kwargs = {'last': 'Doe', 'first': 'John'}
Run Code Online (Sandbox Code Playgroud)
如果我然后进入save_name_for方法,我会看到:
(Pdb) args
self =
args = (<Person: >, (1, 2), {'last': 'Doe', 'first': 'John'})
kwargs =
Run Code Online (Sandbox Code Playgroud)
有没有办法将save_name方法接收到的kwargs直接传递给save_name_for方法,以便它们出现在后者的kwargs中?我想在save_name_for方法的名称空间中看到类似的内容:
(Pdb) args
self =
args = (1, 2)
kwargs = {'last': 'Doe', 'first': 'John'} # <= I want this
Run Code Online (Sandbox Code Playgroud)
我意识到我可以在save_name中解析它们然后将它们显式传递给save_name_for,但这似乎相当不优雅.我还以为我可能会这样做,因为args是一个元组...
kwargs = args[2]
Run Code Online (Sandbox Code Playgroud)
......但它似乎不起作用.args [2]就是一切(我不明白这一点).是否有Pythonic方法来做到这一点?
Mar*_*ers 12
您使用语法镜像参数语法传递它们:
self.save_name_for(*args, **kwargs)
Run Code Online (Sandbox Code Playgroud)
请注意,您无需传入self; save_name_for已经受到约束.
unu*_*tbu 10
在*与**运营商在两个不同的情况下使用.
当用作函数定义的一部分时,
def save_name_for(self, *args, **kwargs):
Run Code Online (Sandbox Code Playgroud)
它分别用于表示任意数量的位置或关键字参数.需要记住的是,函数内部args将是一个元组,并且kwargs将成为一个字典.
当用作函数调用的一部分时,
args = (1, 2)
kwargs = {'last': 'Doe', 'first': 'John'}
self.save_name_for(*args, **kwargs)
Run Code Online (Sandbox Code Playgroud)
在*和**充当拆包经营者.args必须是可迭代的,并且kwargs必须是类似dict的.args
将解压缩项目并将其作为位置参数发送到函数,并将键/值对kwargs作为关键字参数发送到函数.从而,
self.save_name_for(*args, **kwargs)
Run Code Online (Sandbox Code Playgroud)
相当于
self.save_name_for(1, 2, last='Doe', first='John')
Run Code Online (Sandbox Code Playgroud)有关示例的解释,另请参阅saltycrane博客.