从Optional[T]获取Python类型T的变量

bma*_*ies 5 python-3.x python-typing

两个python方法定义为:

   def function() -> Optional[ast.Module]:
      pass

   def something(t: ast.Module) -> None:
      pass
Run Code Online (Sandbox Code Playgroud)

在呼叫者中:

   var = function()
   if var:
     do_something(var)
Run Code Online (Sandbox Code Playgroud)

类型检查器抱怨我无法将Optional[t]传递给t。我想象有某种铸造机制,但我没有想到。

准确地说,这是一个单元测试,如下所示:

    self.assertIsNotNone(var)
    do_something(var)
Run Code Online (Sandbox Code Playgroud)

关于可能重复的可选类型注释。检查是否为“无”后使用值?,

new_var: ast.Module = var
Run Code Online (Sandbox Code Playgroud)

得到相同类型的错误。

是否需要“如果”?

Mis*_*agi 5

必须明确排除该值与 None 相同的情况,而不仅仅是任何 false\xe2\x80\x99y 值。

\n
var: Optional[...] = function()\nif var is not None:    # reject None case in this branch\n    do_something(var)  # `var` is the unwrapped type\n
Run Code Online (Sandbox Code Playgroud)\n

反过来也是可能的:

\n
var: Optional[...] = function()\nif var is None:    # handle None case in this branch\n   ...\nelse:              # no more None case in this branch\n    do_something(var)  # `var` is the unwrapped type\n
Run Code Online (Sandbox Code Playgroud)\n
\n

请注意,类型检查器无法检查类型防护的任意函数。诸如 之类的隐式拒绝self.assertIsNotNone(var)并不等同于针对 的显式检查None。需要额外的、明确的排除。

\n
self.assertIsNotNone(var)\nassert var is not None    # reject None case after this point\ndo_something(var)\n
Run Code Online (Sandbox Code Playgroud)\n

当然,总是可以cast放弃这个选择。由于这会禁用变量类型的验证,因此它通常应该只是最后的手段。

\n
do_something(cast(ast.Module, var))\n
Run Code Online (Sandbox Code Playgroud)\n