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