python - mypy AnyStr 在简单示例的赋值中给出了不兼容的类型

标签 python mypy

给定以下类(class):

from typing import AnyStr

class A(object):

    def __init__(self, param):
        # type: (AnyStr) -> None
        self.a = param # type: AnyStr

我得到以下输出:

$ mypy . -v
LOG:  Mypy version 0.521
LOG:  Build finished in 1.199 seconds with 10 modules, 2076 types, and 2 errors
test.py:8: error: Incompatible types in assignment (expression has type "str", variable has type "AnyStr")
test.py:8: error: Incompatible types in assignment (expression has type "bytes", variable has type "AnyStr"

为什么这个赋值操作会给出不兼容的类型?

最佳答案

我不是 mypy 方面的专家,但通过一些侦探工作,我想我已经解决了这个问题。

问题

这似乎工作得很好,如果 AnyStr传递给函数,但当变量输入为 AnyStr 时失败。例如,这似乎工作正常:

from typing import AnyStr

def f(a):
    # type: (AnyStr) -> AnyStr
    return a

if __name__ == "__main__":
    print(f('cat'))
    print(f(b'dog'))

但这失败了:

from typing import AnyStr

c = 3   # type: AnyStr

出现错误:

mypy_anystr.py:3: error: Invalid type "typing.AnyStr"

这是有道理的,因为 AnyStr 的想法,来自the documentation ,它的目的是或者strbytes ,但它必须在给定函数调用的范围内一致。他们给出的例子是 AnyStr用法是:

def concat(a, b):
    #type: (AnyStr, AnyStr) -> AnyStr
    return a + b

concat('one', 'two')        # OK
concat(b'three', b'four')   # OK
concat('five', b'six')      # Error

当然,除非AnyStr是全局的(上面的例子表明它不是),然后在原始 AnyStr 的范围之外分配一个变量变量(例如全局变量或类的属性)没有意义,这可能是它失败的原因。我怀疑错误消息可能会更清楚地说明这一点。

解决方案

根据您实际想要完成的任务,这里有一些解决方案。如果您确实对str之间不可知论和bytes ,那么您可以使用 Union[Text, bytes] :

通过输入 import Union、Text、AnyStr

class A:
    def __init__(self, a):
        #type: (AnyStr) -> None
        self.param = a  # type: Union[Text, bytes]

请注意,在本例中我使用了 AnyStr在输入上,但在本例中它相当于 Union[Text, bytes] ,因为只有一个参数。或者,如果您确实确实关心参数是否为 strbytes ,你可以直接取 AnyStr并主动将其转换为您想要的版本:

from typing import Union, Text, AnyStr
from six import binary_type
class A:
    def __init__(self, a):
        #type: (AnyStr) -> None
        if isinstance(a, binary_type):
            b = a.decode()  # type: Text
        else:
            b = a

        self.param = b  # type: Text

请注意,如果a,这可能会变得很奇怪。以奇怪的语言环境或其他方式进行编码,因此请注意,这是一个简化的示例,如果您尝试主动解码 bytes,那么请注意,YMMV对象。

关于python - mypy AnyStr 在简单示例的赋值中给出了不兼容的类型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45355329/

相关文章:

python - 在python中的匹配对象中查找字符串

python - TensorFlow 索引无效(越界)

datetime - 注释日期时间对象的推荐方法是什么?

python - 将 matplotlib quiver 和 elipses 结合起来不起作用

python - exe 编译的 Kivy 程序访问图像的问题

Python:如何只迭代字典中的值并附加到值?

python-3.x - 绑定(bind)方法的 MyPy 类型注释?

python - 对抗Python类型注释

python - 如何在不扰乱 mypy 的情况下将元组用作 attr.ib 的转换器?

python - 输入提示 : how should type of lru_cache be defined?