如何区分两种动态类型?

问题描述 投票:1回答:1

我正在对使用pandas的项目进行类型检查。熊猫不包含类型注释,并且排版中没有存根文件。

正如我所期望的,mypy针对这个简单的示例提出了一个错误:

class A:
    def method(self) -> int:
        return 1


class B(A):
    def method(self) -> float:
        return 1.1
$ mypy mypy_example.py 
mypy_example.py:11: error: Return type "float" of "method" incompatible with return type "int" in supertype "A"

请考虑以下示例:

class C:
    def method(self) -> pd.Series:
        return pd.Series([1, 2, 3])


class D(C):
    def method(self) -> pd.DataFrame:
        return pd.DataFrame({"a": [1, 2, 3]})

正如预期的那样,mypy说没有为熊猫找到存根文件,因此找不到错误。

$ mypy mypy_example.py 
mypy_example.py:1: error: No library stub file for module 'pandas'
mypy_example.py:1: note: (Stub files are from https://github.com/python/typeshed)
mypy_example.py:11: error: Return type "float" of "method" incompatible with return type "int" in supertype "A"

我可以设置ignore_missing_imports,但这意味着我错过了我要捕获的错误。

我已经在存根文件中尝试了一些尝试,但均未成功:

from typing import Any, NewType

# dynamic typing, but doesn't discriminate between Series and DataFrame
Series = Any
DataFrame = Any

# discriminates but doesn't dynamically type
Series = NewType('Series', object)
DataFrame = NewType('DataFrame', object)

是否有可能编写一个简短的存根文件或类型注释,以使我能够利用动态键入功能,但会发现pd.Seriespd.DataFrame是不同的类型?

python mypy
1个回答
0
投票

而不是试图让mypy区分两个动态类,我实际上是通过将它们定义为完全成熟的,从而使它们成为动态的(或者更确切地说,仅是[部分动态的)路线存根中的类。您可以通过将两个类定义为如下形式,开始使用非常初步且最少的存根集:

from typing import Any class Series: def __init__(self, *args: Any, **kwargs: Any) -> None: ... def __getattr__(self, name: str) -> Any: ... class DataFrame(Series): def __init__(self, *args: Any, **kwargs: Any) -> None: ... def __getattr__(self, name: str) -> Any: ...

__getattr__函数可让mypy了解您的班级不完整且未完全注释。这意味着即使从未将函数显式添加到您的类中,诸如DataFrame().query(...)之类的操作仍将继续进行类型检查。

当然,如果您

do

决定添加一些方法签名,则mypy将开始对这些调用进行类型检查,而不是动态地对其进行键入。这意味着您也可以根据需要逐步添加更精确的方法签名,并且最终可能完全摆脱__getattr__

如果您决定采用此路线,可能会发现现有的numpy stubs是很好的灵感来源。而且,如果您想要真正精确的类型,则discussion here可能是相关的。

如果您有好奇心,writing incomplete stubs上的排版指南会提供更多有关编写部分存根的信息。
© www.soinside.com 2019 - 2024. All rights reserved.