代码之家  ›  专栏  ›  技术社区  ›  ubiquibacon

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

  •  0
  • ubiquibacon  · 技术社区  · 5 年前

    有没有办法让Mypy不打电话就知道我在处理什么类型的对象 isinstance 在每个if语句中?我希望有助手函数来做这类事情,但即使我有 存在 在helper函数中,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
    
    0 回复  |  直到 5 年前
        1
  •  3
  •   Markus Unterwaditzer    5 年前

    考虑改变你的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)