【问题标题】:How to pass through Python args and kwargs?如何通过 Python args 和 kwargs?
【发布时间】:2023-03-19 21:19:01
【问题描述】:

虽然我对 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()

我已将保存名称拆分为上面的两个函数。通过这种方式,我可以通过对 save_name_for 方法进行单元测试来对通常将所有内容放在 save_name 方法中的逻辑进行单元测试。

当我在解释器中运行它并在 save_name 方法中停止时,正如我所料,我看到了:

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

如果我随后进入 save_name_for 方法,我会看到:

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

有没有办法将 save_name 方法接收到的 kwargs 直接传递给 save_name_for 方法,以便它们出现在后者的 kwargs 中?我希望在 save_name_for 方法的命名空间中看到类似的内容:

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

我意识到我可以在 save_name 中解析它们,然后将它们显式传递给 save_name_for,但这似乎很不优雅。我还想我可能会这样做,因为 args 是一个元组......

kwargs = args[2]

...但它似乎不起作用。 args[2] 就是一切(我不明白这一点)。有没有 Pythonic 的方式来做到这一点?

【问题讨论】:

    标签: python


    【解决方案1】:

    *** 运算符用于两种不同的情况。

    1. 当用作函数定义的一部分时,

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

      用于表示任意数量的位置或关键字 论据,分别。要记住的一点是,在 函数 args 将是一个元组,而 kwargs 将是一个 字典

    2. 当用作函数调用的一部分时,

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

      *** 充当解包操作符args 必须是 可迭代,并且kwargs必须是dict-likeargs中的项目 将被解包并作为位置参数发送到函数, kwargs 中的键/值对将作为 关键字参数。因此,

      self.save_name_for(*args, **kwargs)
      

      等价于

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

    另请参阅saltycrane blog 以获取示例说明。

    【讨论】:

      【解决方案2】:

      您使用与参数语法相同的语法来传递它们:

      self.save_name_for(*args, **kwargs)
      

      注意不需要传入selfsave_name_for 已绑定。

      【讨论】:

      • 如果有人感兴趣,我刚刚看到这篇文章更详细地描述了 Martijn 给出的答案:tinyurl.com/d99sgkw
      • 我想知道,为什么他们在 Python 日志记录代码中的做法不同:i.imgur.com/pTyL5CI.png - 它在调用 args 之前缺少 * args
      • @JustAMartin 因为Logger._log() method 期望值作为序列插入到记录的消息中,单个参数。它不希望这些作为单独的论点。 method(*args, **kwargs) 模式不适用于那里,因为没有隐藏方法签名的意图,Logger._log() 是一个内部方法,公共 Logger.info() 不需要假装它接受相同的参数。
      猜你喜欢
      • 1970-01-01
      • 2020-09-16
      • 2017-01-28
      • 2018-08-28
      • 2021-07-26
      • 2022-09-22
      • 2010-10-24
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多