【问题标题】:Python 3 type hinting for None?无的 Python 3 类型提示?
【发布时间】:2013-10-12 17:10:36
【问题描述】:
def foo(
        hello: str='world', bar: str=None,
        another_string_or_None: str|????=None):
    pass

我正在尝试在 Python 中的函数中设置类型提示,您可以使用 something: str|bool='default value' 添加多个类型提示,但是,None 的类型提示是什么? :/

【问题讨论】:

  • 为什么要暗示给定变量应该始终为 NoneType?
  • 因为可以是 None 或 str
  • 您使用什么工具来读取这些注释?
  • 什么是默认状态(没有传递参数)?无还是字符串?
  • Python 3 没有类型检查。它有 pep 3107 注释,一些外部工具可能会考虑类型提示。 pep 明确地不为注释分配任何语义。

标签: python python-3.x nonetype type-hinting


【解决方案1】:

从你的例子:

def foo(
        hello: str='world', bar: str=None,
        another_string_or_None: str|????=None):
    ...

我注意到您的用例是“有或无”。

从 3.5 版开始,Python 支持通过 typing module 进行类型注释。 在您的情况下,推荐的注释方式是使用typing.Optional[something] hint。这具有您正在寻找的确切含义。

因此another_string_or_None 的提示是:

import typing

def foo(
        hello: str='world', bar: str=None,
        another_string_or_None: typing.Optional[str]=None):
    ...

【讨论】:

  • 这就是我想要做的可选类型语义。或者,要进行变体类型语义,typing.Union 存在,或者如果您关心多个签名到返回类型的映射,@typing.overload 也存在
  • @solstice333 是的,作为我回答的旁注:typing.Union[None, ABC] 与 typing.Optional[ABC] 的工作方式相同。如果你有 typing.Optional[typing.Union[int, str]],你可以把它改成 typing.Union[None, int, str]。
【解决方案2】:

只是None

>>> def nothing(nun: None) -> None:
...     return nun
... 
>>> nothing(None)
>>> 

或者至少,它可以是。

由于这些注释对 Python 来说除了语法正确/没有任何意义,这在某种程度上取决于工具。

例如,如果您使用typecheck-decorator,则you'll need to 使用type(None)

>>> import typecheck as tc
>>>
>>> @tc.typecheck
>>> def nothing(nun: type(None)) -> type(None):
...     return nun
... 
>>> nothing(None)
>>> nothing(0)
typecheck.framework.InputParameterError: nothing() has got an incompatible value for nun: 0
>>> nothing(False)
typecheck.framework.InputParameterError: nothing() has got an incompatible value for nun: False

Typecheck 还允许您使用tc.any() (OR)、tc.all() (AND) 等更清楚地“添加不止一种类型提示”。

注意tc.none() 是一个类似于 NAND 的谓词; 不是您要查找的内容 - 没有参数,它将接受 any 类型,相当于 tc.all() 或更贴切的 tc.anything

【讨论】:

    【解决方案3】:

    Python 3.10(在撰写本文时处于测试阶段)将支持您最初所需的符号:str | None

    Source

    【讨论】:

    • 终于!好消息,谢谢
    【解决方案4】:

    感谢@mbdevpl,我知道这个问题被认为已得到回答,但是,我想补充一点,type(None) 是您获得 None 类型的实际方法,这在if statement check 中很有用,例如:

    if isinstance(x_var, type(None)):
        pass
    

    并且由于python3.5,您还可以使用do Union of a一堆类型和None,如下所示:

    x_var: typing.Union[str, None]
    y_var: typing.Union[Dict, List, None]
    

    这相当于:

    x_var: typing.Optional[str]
    y_var: typing.Optional[typing.Union[Dict, List]]
    

    【讨论】:

    • 我不认为typing.Union[str, None] 在所有情况下都等同于typing.Optional[str]。考虑一种情况,您有一个TypedDict,其中一个属性必须是strNone,但不能省略:``` class MyClass(TypedDict): required_field: Union[str, None] `` `
    • @Stevula 是的,我想问这个问题,我假设如果你有一个 dict 的键是 Nonestr 你会使用 Union[str,None]不是Optional[str],因为dict 键不是可选的?
    猜你喜欢
    • 2017-12-07
    • 1970-01-01
    • 2018-04-14
    • 1970-01-01
    • 2020-10-24
    • 2020-01-26
    • 2019-02-08
    相关资源
    最近更新 更多