通过简单的字典使用kwarg(或args)有什么好处?

Gui*_*reg 6 python dictionary kwargs

我想知道为什么我应该使用kwargs或args而不是传递简单的dict(如果是args,则使用元组)?

我写了一个非常简单的代码片段来检查到底发生了什么,而我找不到任何专家在字典上使用kwarg。如果有人能告诉我为什么我应该使用那些,我会很高兴的。现在,正如我所看到的,它只是更多的pythonic,但没有任何区别。同样,如果您使用简单的字典,那么它会更易读,因为所有语言都可以做到这一点,但不能采用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')
Run Code Online (Sandbox Code Playgroud)
Type: <class 'dict'>, raw: {'name': 'Joseph'}
key: name, value: Joseph
Type: <class 'dict'>, raw: {'name': 'Joseph'}
key: name, value: Joseph
Run Code Online (Sandbox Code Playgroud)

Yev*_*ych 6

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

有几个整齐的用例的*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
Run Code Online (Sandbox Code Playgroud)

如您所见,类A并不关心Base__init__参数,因此它只是将所有内容(除了n需要的内容)向前传递。所以,如果你要改变Base__init__,你就不需要改变A

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

a = A(5, 3, y=6, z=42)
Run Code Online (Sandbox Code Playgroud)

一个类似的想法是当您实现一个装饰器,该装饰器要用于具有任何种类和数量的参数的函数时:

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)
Run Code Online (Sandbox Code Playgroud)

然后:

>>> foo(42)
Hello
42

>>> bar(1, 2, c=3)
Hello
9
Run Code Online (Sandbox Code Playgroud)