首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何区分两种动态类型?

如何区分两种动态类型?
EN

Stack Overflow用户
提问于 2019-10-28 11:18:38
回答 1查看 268关注 0票数 2

我正在检查一个使用熊猫的项目。熊猫不包含类型注释,并且在类型中没有存根文件。

正如我所预期的,mypy会为这个简单的示例引发一个错误:

代码语言:javascript
复制
class A:
    def method(self) -> int:
        return 1


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

请考虑以下示例:

代码语言:javascript
复制
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说没有找到熊猫的存根文件,所以没有发现错误。

代码语言:javascript
复制
$ 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,但这意味着我错过了想要捕获的错误。

我尝试过一些存根文件中的内容,但都没有成功:

代码语言:javascript
复制
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是不同的类型?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2019-10-28 18:05:22

与其试图区分两个动态类,不如通过将它们定义为存根中的完整类,从而使它们不再是动态的(或者说是部分动态的)。

通过将两个类定义为如下所示,您可以开始使用非常初步和最小的存根集:

代码语言:javascript
复制
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(...)之类的操作将继续进行类型检查,即使该函数从未显式地添加到您的类中。

当然,如果您确实决定添加一些方法签名,mypy将开始键入这些调用,而不是让它们动态键入。这意味着,如果需要,还可以逐步添加更精确的方法签名,并且可能最终完全摆脱__getattr__

如果您决定走这条路,您可能会发现现有的块茎是一个很好的灵感来源。如果您想要真正精确的类型,在这里讨论可能是相关的。

如果您有兴趣的话,写不完整存根上的类型化指南包含更多关于编写部分存根的信息。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/58589999

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档