如何在函数中实现 **kwargs 来省略参数?

huangapple go评论88阅读模式
英文:

How do I implement **kwargs to omit arguments in a function?

问题

我正在寻找能够尽可能简单地解释解决方案的人

在创建一个函数时,我想知道是否可以将函数中的某些参数设为可选的。通常情况下,我会收到一个错误消息,说“缺少 1 个必需的位置参数:'arg1'”。使用 **kwargs 可能会起作用,有人可以向我解释这个吗?

这是我想要实现的目标。

def myFunc(arg1, arg2, arg3):
    print(arg1)
    print(arg2)
    print(arg3)

myFunc(arg3)
英文:

I'm looking for someone who can explain a solution as simply as possible

When making a function, I was wondering if it was possible to optionalize certain arguments in a function. Usually I would get an error saying missing 1 required positional argument: 'arg1'. using **kwargs may work, any way someone can explain this to me?

This is what I'm trying to accomplish.

def myFunc(arg1, arg2, arg3):
    print(arg1)
    print(arg2)
    print(arg3)

myFunc(arg3)

答案1

得分: 2

**kwargs 收集与函数定义中明确命名的参数不对应的关键字参数。这是一种接受并可能忽略额外关键字参数的合理方式,但它不允许调用者省略参数。还要注意,名称kwargs只是一种约定。**才是功能上重要的部分;名称可以是任何内容。

对于位置参数的类似语法是*args,但同样,这不允许调用者省略参数;相反,它允许调用者提供额外的位置参数。

在你的特定示例中,似乎arg1arg2arg3 都具有相同的重要性,所以你可以考虑像这样的方式:

def myFunc(*args):
    for arg in args:
        print(arg)

这将接受任意数量的位置参数,包括零个,并打印每个给定的参数。你甚至可以将其泛化为:

def myFunc(*args, **kwargs):
    for arg in args:
        print(arg)
    for arg in kwargs.values():
        print(arg)

,这将打印出位置参数和关键字参数的值。

但在你的示例中,你建议这样做:

myFunc(arg3)

,如果myFunc() 对于第三个参数的重要性与第一个参数的重要性不同,那么它无法按照你的要求工作。Python 如何将其与 myFunc(arg1) 区分开呢?但你可以通过以下方式支持这一点:

  1. 为一些或全部参数提供默认值。对于此目的,None 通常是一个不错的选择。并且

  2. 期望调用者通过使用关键字参数来处理这种情况。

示例:

def myFunc(arg1=None, arg2=None, arg3=None):
    if arg1 is not None:
        print(f'arg1 is {arg1}')
    if arg2 is not None:
        print(f'arg2 is {arg2}')
    if arg3 is not None:
        print(f'arg3 is {arg3}')

myFunc(arg3='foo')
英文:

> How do I implement **kwargs to omit args in a function?

**kwargs collects keyword arguments that do not correspond arguments explicitly named in the function definition. This is a fair way to accept, and possibly ignore, extra keyword arguments, but it does not provide for the caller to omit arguments. Note also that the name kwargs is just a convention. It is the ** that is functionally important; the name can be anything.

The analogous syntax for positional arguments is *args, but again, this does not provide for callers to omit arguments; rather, it provides for callers to provide extra positional arguments.

In your particular example, it seems that arg1, arg2, and arg3 all have equivalent significance, so you could consider something like this:

def myFunc(*args):
    for arg in args:
        print(arg)

That will accept any number of positional arguments, including zero, and print each one given. You could even generalize that to

def myFunc(*args, **kwargs):
    for arg in args:
        print(arg)
    for arg in kwargs.values():
        print(arg)

, which prints both positional and keyword argument values.

But in your example, you suggest

myFunc(arg3)

, and if the significance to myFunc() of the third argument is different than the significance of the first then there's no way for that to work as you want. How can Python distinguish it from myFunc(arg1)? But you can support that by

  1. Giving some or all arguments default values. None is often a good choice for this purpose. AND

  2. Expecting the caller to exercise this case by use of a keyword argument.

Example:

def myFunc(arg1=None, arg2=None, arg3=None):
    if arg1 is not None:
        print(f'arg1 is {arg1}')
    if arg2 is not None:
        print(f'arg2 is {arg2}')
    if arg3 is not None:
        print(f'arg3 is {arg3}')

myFunc(arg3='foo')

答案2

得分: 0

你应该在元素类似于列表时使用 fo(*argv),在想要键值对(字典)时使用 fo(**kwargs)

一个示例

def fo(**kwargs):
    for key, value in kwargs.items():
        print(value)

fo(name="Alice", name2="Bob")

将打印出

Alice
Bob

你也可以使用相同的方法

def fo(*args):
    for value in args:
        print(value)

fo("Alice", "Bob")
英文:

you should use fo(*argv) if the elements are like a list and fo(**kwargs) if you want key-value pairs (dictionary).

An example

def fo(**kwargs):
    for key, value in kwargs.items():
        print(value)

fo(name="Alice", name2="Bob")

will print you

Alice
Bob

You can do the same thing with

def fo(*args):
    value in args:
        print(value)

fo("Alice", "Bob")

答案3

得分: 0

将所有参数改为关键字参数:

def myFunc(arg1=None, arg2=None, arg3=None):
    ...

然后可以根据需要调用函数,传入任意数量的参数:

myFunc(arg1="hello", arg2="apple")
myFunc(arg2="goodbye")
myFunc(arg3="abc")
英文:

Make all of the args keyword args:

def myFunc(arg1=None, arg2=None, arg3=None):
    ...

Then call the function with as many or as few of the args as you like:

myFunc(arg1="hello", arg2="apple")
myFunc(arg2="goodbye")
myFunc(arg3="abc")

答案4

得分: 0

将参数变为可选的规范方式是定义一个默认值。如果将默认值设置为None,然后可以通过检查它们是否为None来处理它们。

def myFunc(arg1=None, arg2=None, arg3=None):
    print(arg1)
    print(arg2)
    print(arg3)

myFunc(arg3=arg3)

然而,在处理位置参数时,这种方法不起作用,因为myfunc(arg3)会将arg3的值分配给您作用域的arg1。为了确保不发生这种情况,您可以使用“*”强制使用关键字参数。

def myFunc(*, arg1=None, arg2=None, arg3=None):
    print(arg1)
    print(arg2)
    print(arg3)

当您在不使用关键字时调用myFunc(arg3)时,会引发异常。当然,**kwargs 也可以工作。然后,您可以使用 kwargs.get("arg1", None) 来获取默认值为None(或其他值)。

英文:

The canonical way to make arguments optional would be to define a default.
If you set the default to None, you could then proceed by checking if they are None and handle them accordingly.

def myFunc(arg1=None, arg2=None, arg3=None):
    print(arg1)
    print(arg2)
    print(arg3)

myFunc(arg3=arg3)

This doesn't work with positional arguments though, because myfunc(arg3) would assign the value of arg3 to arg1 in the context of your scope.
To make sure this doesn't happen, you could enforce keyword arguments by using the "*".

def myFunc(*, arg1=None, arg2=None, arg3=None):
    print(arg1)
    print(arg2)
    print(arg3)

this would raise an Exception when you are calling myFunc(arg3) without using the keyword.
Of course, **kwargs would work as well. You could then use kwargs.get("arg1", None) to get a default value of None (or something else).

huangapple
  • 本文由 发表于 2023年7月28日 04:18:52
  • 转载请务必保留本文链接:https://go.coder-hub.com/76783146.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定