如何让Mypy意识到isinstance已被调用?

2024-05-17 08:46:37 发布

您现在位置:Python中文网/ 问答频道 /正文

有没有办法让Mypy意识到我知道我在处理什么类型的对象,而不必在每个if语句中调用isinstance?我想让helper函数来做这类事情,但即使helper函数中有isinstance,Mypy也会抱怨。我也尝试过使用typing.Union来解决这个问题,但也遇到了类似的问题。你知道吗

import typing


class A:
    def __init__(self, a):
        self.a = a

    def is_b(self):
        return isinstance(self, B)

    def is_c(self):
        return isinstance(self, C)


class B(A):
    def __init__(self, a, b):
        self.b = b

        super().__init__(a)


class C(A):
    def __init__(self, a, c):
        self.c = c

        super().__init__(a)


a_list: typing.List[A] = []
for i in range(0, 10):
    b_or_c: A
    if i % 2 == 0:
        b_or_c = B('a' + str(i), 'b' + str(i))
    else:
        b_or_c = C('a' + str(i), 'c' + str(i))

    a_list.append(b_or_c)

for b_or_c in a_list:
    print(type(b_or_c))
    if b_or_c.is_b():
        print(b_or_c.b)  # Mypy Error: "A" has no attribute "b"

    if b_or_c.is_c():
        print(b_or_c.c)  # Mypy Error: "A" has no attribute "c"

    if isinstance(b_or_c, B):
        print(b_or_c.b)  # No Mypy Error

    if isinstance(b_or_c, C):
        print(b_or_c.c)  # No Mypy Error

Tags: orselfhelpertypingifinitisdef
1条回答
网友
1楼 · 发布于 2024-05-17 08:46:37

考虑从以下方面更改API:

def is_c(self) -> bool:
    return isinstance(self, C)

对此:

def as_c(self) -> Optional[C]:
    if isinstance(self, C):
        return self
    return None

这将完全避免问题。你可以这样使用它:

c_opt = b_or_c.as_c()
if c_opt is not None:
    print(c_opt.c)

相关问题 更多 >