问题描述
我有一个 ast.UnaryOp
对象,但我手动添加了一个 parent
属性(请参阅 answer)。如何在函数中对此进行注释?
我目前只有:
def _get_sim206(node: ast.UnaryOp):
if isinstance(node.parent,ast.If):
return False
return True
但 mypy 抱怨(理所当然)ast.UnaryOp
没有 parent
属性。
我如何告诉 mypy node
不是 ast.UnaryOp
而是 ast.UnaryOp + parent attribute
?
我的尝试
我创建了自己的 UnaryOp
类,它具有父属性。我可以用它来进行类型转换:
class UnaryOp(ast.UnaryOp):
def __init__(self,orig: ast.UnaryOp) -> None:
self.op = orig.op
self.operand = orig.operand
self.lineno = orig.lineno
self.col_offset = orig.col_offset
self.parent: ast.Expr = orig.parent # type: ignore
它的缺点是我需要在很多地方输入类型转换并且我引入了 Any
。如果我可以在某处声明该文件中的所有 ast.*
类型确实具有 parent
属性
解决方法
作为一种解决方法,您可以将 isinstance()
与 protocol 一起使用 @runtime_checkable 修饰,这将在运行时检查所有协议成员是否已定义并确保静态正确性。
from typing import Protocol,runtime_checkable,cast
import ast
@runtime_checkable
class ParentProto(Protocol):
parent: ast.AST
def foo(node: ast.UnaryOp):
if isinstance(node,ParentProto):
# use node.parent
p = node.parent
l = node.lineno
# assignment
g = ast.UnaryOp()
cast(ParentProto,g).parent = ast.If()