【问题标题】:What is the benefit of using kwargs (or args) over a simple dict?使用 kwargs(或 args)而不是简单的 dict 有什么好处?
【发布时间】:2019-09-02 12:17:29
【问题描述】:

我想知道为什么我应该使用 kwargs 或 args 而不是传入一个简单的 dict(或 args 的元组)?

我编写了一个非常简单的代码 sn-p 来检查到底发生了什么,但我找不到任何专业人士可以在 dict 上使用 kwargs。如果有人能告诉我为什么要使用那些我会很高兴的。 现在我可以看到它更像是pythonic,但没有任何区别。此外,如果您使用简单的 dict,那么它的可读性更高,因为所有语言都可以做到这一点,但 kwargs 方式却不行。

def test_normal(input: dict):
    for element in input.items():
        print('Type: {}, raw: {}'.format(type(input), input))
        print('key: {}, value: {}'.format(element[0], element[1]))

def test_kwargs(**kwargs):
    for element in kwargs.items():
        print('Type: {}, raw: {}'.format(type(kwargs), kwargs))
        print('key: {}, value: {}'.format(element[0], element[1]))

test_normal(dict(name='Joseph'))
test_kwargs(name='Joseph')
Type: <class 'dict'>, raw: {'name': 'Joseph'}
key: name, value: Joseph
Type: <class 'dict'>, raw: {'name': 'Joseph'}
key: name, value: Joseph

【问题讨论】:

  • 因为test_kwargs(name='Joseph')看起来比test_normal(dict(name='Joseph'))好很多
  • 您的问题过于宽泛,请尝试将您的示例扩展为一个需要多个参数才能开始的函数。
  • kwargs 的想法是一个干净的接口,允许输入参数不一定是预先确定的。这样你就不必把它扔进字典里了。参见this post
  • @busybear 是的,您不必将其放入字典中,但是当您尝试在方法中使用它时,它仍然是字典。

标签: python dictionary keyword-argument


【解决方案1】:

这些是不同的东西,都有各自的用例。只是一个经验法则:如果它看起来像一个函数参数,它应该是一个函数参数

*args**kwargs 有几个简洁的用例。其中之一是传递您此时不关心的参数:

假设你有类Base 和类A 继承自Base

class Base:
    def __init__(self, x, y, z):
        self.x = x
        self.y = y
        self.z = z

class A(Base):
    def __init__(self, n, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self.n = n

如您所见,A 类不关心Base__init__ 参数,因此它只是将所有内容(除了它需要的n)传递。因此,如果您要更改 Base__init__,则无需更改 A

但是当您创建A 对象时,您会正常传递参数:

a = A(5, 3, y=6, z=42)

一个类似的想法是当你实现一个装饰器时,你想在一个函数上使用任何类型和数量的参数:

def say_hello_first(fn):
    def wrapper(*args, *kwargs):
        print('Hello')
        return fn(*args, **kwargs)
    return wrapper

@say_hello_first
def foo(x):
    print(x)

@say_hello_first
def bar(a, b, c=3.14):
    print((a + b) * c)

然后:

>>> foo(42)
Hello
42

>>> bar(1, 2, c=3)
Hello
9

【讨论】:

  • 第二部分对装饰器很有意义。
猜你喜欢
  • 2016-02-06
  • 2016-09-03
  • 2017-03-26
  • 1970-01-01
  • 1970-01-01
  • 2019-11-17
  • 2010-09-14
  • 2022-08-03
  • 2016-05-26
相关资源
最近更新 更多