繁体   English   中英

mypy:基类没有属性 x,如何在基类中键入提示

[英]mypy: base class has no attribute x, how to type hint in base class

我最近发现了 mypy,我希望用它对我的代码进行类型检查。

我有一个Connector基类:

class Connector():
    ... some methods, but no __init__ ...

我有几个子类,它们都是连接器,但类型不同:

class Siphon(Connector)
    def __init__():
        short_name = "S"


class Tube(Connector)
    def __init__():
        short_name = "T"

当我使用这些对象时,我通常将它们放在一个列表中:

c1 = Siphon()
c2 = Tube()
list_connectors: List[Connector] = list()
list_connectors.append(c1)
list_connectors.append(c2)

现在假设我想编写一个函数来返回所有连接器的所有短名称,作为列表。 我会写这样的东西:

def get_names(list_connectors: List[Connector]) -> List[str]:
    tmp_list: List[str] = list()
    for c in list_connectors:
        tmp_list.append(c.short_name)
    return tmp_list

当我这样做时,mypy 抱怨:

error: "Connector" has no attribute "short_name"

这是真的,基类连接器没有这个属性,只有子类。 但是所有连接器子类都将具有此属性。

我应该如何纠正? 我不能在这里使用类属性,因为我的所有子类都需要它们自己的short_name属性。

我是否应该在get_names函数的类型提示中使用 Union(在我的现实生活中,连接器类型远不止 2 种,我的 API 的用户可以添加他自己的连接器)?

我也不确定我是否可以编写一个基本的__init_函数并在子类中覆盖它,因为子类都有不同的 init

您可以将该属性添加到基本类型; 你不需要给它一个值:

class Connector:
    short_name: str

这使用 Python 3.6 的变量注释语法,这是 Python 3.6 或更新版本中的新内容。 它定义了一个实例属性的类型,而不是一个类属性(有一个单独的语法)。

否则你可以使用注释,此时你必须给属性一个初始值,并且是一个类属性:

class Connector:
   short_name = ''  # type: str

如果您使用的是 python 3.6 或更高版本,那么

class Connector():
    short_name: str
    ...

应该管用。 这实际上并不存在于命名空间中,但 MYPY 会找到它。 请参阅https://www.python.org/dev/peps/pep-0526/


另一种选择是做

import abc
class Connector(abc.ABC):
    @property
    @abc.abstractmethod
    def short_name(self) -> str:
        ...

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM