使用类型提示时如何向函数添加默认参数?

Posted

技术标签:

【中文标题】使用类型提示时如何向函数添加默认参数?【英文标题】:How do I add default parameters to functions when using type hinting? 【发布时间】:2016-12-08 05:26:00 【问题描述】:

如果我有这样的功能:

def foo(name, opts=):
  pass

我想给参数添加类型提示,我该怎么做?我假设的方式给了我一个语法错误:

def foo(name: str, opts=: dict) -> str:
  pass

以下内容不会引发语法错误,但似乎不是处理这种情况的直观方式:

def foo(name: str, opts: dict=) -> str:
  pass

我在 typing documentation 或 Google 搜索中找不到任何内容。

编辑:我不知道默认参数在 Python 中是如何工作的,但为了这个问题,我将保留上面的示例。一般来说,最好执行以下操作:

def foo(name: str, opts: dict=None) -> str:
  if not opts:
    opts=
  pass

【问题讨论】:

最后一个函数是正确的方法。 scala 语言也是如此。 你有一个可变的默认类型——这会导致问题 @noɥʇʎԀʎzɐɹƆ 除非您将其用于,例如记忆。 :P 【参考方案1】:

你的第二种方法是正确的。

def foo(opts: dict = ):
    pass

print(foo.__annotations__)

这个输出

'opts': <class 'dict'>

确实它没有在PEP 484 中列出,但类型提示是函数注释的应用,在 PEP 3107 中有记录。The syntax section 清楚地表明关键字参数以这种方式与函数注释一起使用。

我强烈建议不要使用可变关键字参数。更多信息here。

【讨论】:

见legacy.python.org/dev/peps/pep-3107/#syntax。类型提示只是函数注解的一种应用。 哇,我不知道 Python 中的可变默认参数......尤其是来自 javascript/Ruby,其中默认参数的工作方式不同。不会重复已经说过的关于它的恶心,我很高兴我在它咬我之前发现了这一点。谢谢! 我总是被建议使用 None 而不是像 或 [] 这样的可变类型或默认对象,因为没有深拷贝的对象的突变将在迭代之间持续存在。 用可变的关键字参数定义足够多的函数,然后你会发现自己回顾 4 小时的调试会议来质疑你的生活选择只是时间问题 不应该在dict = 中的= 周围没有空格,就像它是非类型提示关键字参数的约定一样?【参考方案2】:

如果您使用typing(在 Python 3.5 中引入),您可以使用typing.Optional,其中Optional[X] 等效于Union[X, None]。它用于表示None 的显式值是允许的。来自typing.Optional:

def foo(arg: Optional[int] = None) -> None:
    ...

【讨论】:

不应该在Optional[int] = None 中的= 周围没有空格,就像它是非类型提示关键字参数的约定一样? @actual_panda 答案是正确的。当有类型提示时,样式会有所不同。 PEP 484中有例子【参考方案3】:

我最近看到了这个单行:

def foo(name: str, opts: dict=None) -> str:
    opts =  if not opts else opts
    pass

【讨论】:

嗨@Kirkalicious,感谢您的回答。你能解释一下它是如何工作的吗? 作为默认参数传递的空字典对于每个调用都是相同的字典。因此,如果函数对其进行了变异,那么下一次的默认值将是上次的变异值。将 None 设为默认值,然后在方法内部进行检查,可以通过在每次调用方法时分配一个新的 dict 来避免此问题。 你能update your answer(没有“编辑:”、“更新:”或类似的)吗?评论可能随时消失。 opts = opts or 怎么样 这有一个问题——如果 opts 是一个可变参数,调用者希望在其中看到修改后的值,则在传入 时它将失败。可能更安全坚持传统的两班制if opts is None: opts = 。如果您需要单线,我更喜欢opts = if opts is None else opts

以上是关于使用类型提示时如何向函数添加默认参数?的主要内容,如果未能解决你的问题,请参考以下文章

Vue函数有回调参数,添加参数时如何保留默认回调参数

Vue函数有回调参数,添加参数时如何保留默认回调参数

Vue函数有回调参数,添加参数时如何保留默认回调参数

如何使用参数(通过 HTTP)向 NTLM 进行身份验证?

Python 可变类型作为函数默认参数时的副作用

C++ —— 函数默认参数