如何使用可选参数创建Python函数?

Tha*_*lia 162 python arguments function optional-arguments

我有一个Python函数,它需要几个参数.在某些情况下,可以省略其中一些参数.

def some_function (self, a, b, c, d = None, e = None, f = None, g = None, h = None):
    #code
Run Code Online (Sandbox Code Playgroud)

这些参数d通过h是字符串,每个都有不同的含义.重要的是我可以选择以任意组合传递哪些可选参数.例如,(a, b, C, d, e)(a, b, C, g, h),或(a, b, C, d, e, f,或全部(这些是我的选择).

如果我可以重载函数会很棒 - 但我读到Python不支持重载.我试图在列表中插入一些必需的int参数 - 并得到一个参数不匹配错误.

现在我发送空字符串代替前几个缺少的参数作为占位符.我希望能够使用实际值调用函数.

有没有办法做到这一点?我可以传递一个列表而不是参数列表吗?

现在使用ctypes的原型看起来像:

_fdll.some_function.argtypes = [c_void_p, c_char_p, c_int, c_char_p, c_char_p, c_char_p, c_char_p, c_char_p]
Run Code Online (Sandbox Code Playgroud)

Nix*_*Nix 187

只需使用*args参数,它允许您在您之后传递任意数量的参数 a,b,c.你必须添加一些逻辑来映射args-> c,d,e,f但它是一种重载的"方式".

def myfunc(a,b, *args, **kwargs):
   for ar in args:
      print ar
myfunc(a,b,c,d,e,f)
Run Code Online (Sandbox Code Playgroud)

它会打印出来 c,d,e,f


类似地,您可以使用kwargs参数,然后您可以命名您的参数.

def myfunc(a,b, *args, **kwargs):
      c = kwargs.get('c', None)
      d = kwargs.get('d', None)
      #etc
myfunc(a,b, c='nick', d='dog', ...)
Run Code Online (Sandbox Code Playgroud)

然后kwargs会有一个字典,其中包含所有关键值的参数 a,b

  • 它被称为[任意参数列表](http://docs.python.org/tutorial/controlflow.html#arbitrary-argument-lists) (10认同)
  • 谢谢。虽然我无法在代码中使用如此大的灵活性,并且它不能解决我使用列表中的各种空洞进行调用的问题,但它是在不同项目中使用的一个很好的工具。拉塞尔·博罗戈夫(Russel Borogove)为我的问题提供了所需的确切答案,我很高兴。 (2认同)
  • @Nix,我真的很喜欢你的回答。但是,您能否澄清一下语句 `c = kwargs.get('c', None)` 的用途是什么?每个具有可选参数的函数都需要它吗?在您的代码中,您只有 2 个可选参数。如果用户想要另一个参数“e”怎么办?我如何更改示例代码以获取任何未知数量的可选参数,例如:`def my_func(a, b, *args, **kwagars): obj = <用 a & b 做某事> obj.add(c) obj.add(d) 继续 obj.add(for e, f, g...)`?在执行 `obj.add(c, d, ...)` 之前,我是否必须包含 `c = kwargs.get('c', None) 等`? (2认同)

Rus*_*ove 152

试着称之为:obj.some_function( '1', 2, '3', g="foo", h="bar" ).在所需的位置参数之后,您可以按名称指定特定的可选参数.


Avi*_*ión 25

必需参数在前,可选参数在后。可选参数始终带有=None.

简单快速的例子:

def example_function(param1, param2, param3=None, param4=None):
    pass

# Doesn't work, param2 missing
example_function("hello")

# Works
example_function("hello", "bye")

# Works. Both the same
example_function("hello", "bye", "hey")
example_function("hello", "bye", param3="hey")

# Works. Both the same
example_function("hello", "bye", "hey", "foo")
example_function("hello", "bye", param3="hey", param4="foo")
Run Code Online (Sandbox Code Playgroud)

  • ** 必填参数在前,可选参数在后。** 这是关键。 (2认同)

PYC*_*PYC 16

这样做很容易

def foo(a = None):
       print(a)
Run Code Online (Sandbox Code Playgroud)

如果没有参数,您可以输入任何应该到位的内容,而不是 None,例如,如果您不会像这样写入参数的值,foo()那么它将打印 None 因为没有给出参数,如果您将给它一个参数,foo("hello world")那么它会打印hello world,哦,是的,我忘了告诉大家,当这些类型的参数即可选参数时,这些参数需要遵循默认参数,这意味着,让我们使用前一个函数并添加另一个参数b

def foo(a = None, b): 
    print(a)
Run Code Online (Sandbox Code Playgroud)

现在,如果你要执行你的 python 文件,它会引发一个异常,说Non-default arguments follows default arguments

SyntaxError: non-default argument follows default argument
Run Code Online (Sandbox Code Playgroud)

所以你必须把可选的或非默认的参数放在需要的参数之后

意思是

def foo (a, b=None): ... #This one is right(these threee dots are ellipsis which are somewhat like pass

def foo(b=None, a): ... #and this isn't
Run Code Online (Sandbox Code Playgroud)


cem*_*cem 16

检查一下:

from typing import Optional

def foo(a: str, b: Optional[str] = None) -> str or None:
    pass
Run Code Online (Sandbox Code Playgroud)

  • 但这些注释在运行时不会用于强制执行甚至检查参数类型。所以这不是正确的方法,它实际上并没有达到OP想要的效果。 (3认同)
  • 这两个并不等价: * 在第一个示例中,'b' 仍然是必须提供的位置参数: * 在第二个示例中,'b' 是一个可以省略的真正的可选参数(在这种情况下将如果省略,则值为 None)。使参数真正可选的是参数列表中的“= <value>”——Optional[...] 注释与参数是位置参数还是可选参数无关。 (2认同)