【问题标题】:Typing: incompatible type when declare typing.Type[]打字:声明打字时类型不兼容。Type []
【发布时间】:2017-02-03 14:26:21
【问题描述】:

如下代码

# -*- coding: utf-8 -*-
import typing


class A(object):
    pass

class B(A):
    pass

class C(A):
    pass

class D(A):
    pass

class E(A):
    pass

MAPPING_X = {
    B: 'b',
    C: 'c',
}
MAPPING_Y = {
    D: 'd',
    E: 'e',
}

all_mappings = {}  # type: typing.Dict[typing.Type[A], str]
all_mappings.update(MAPPING_X)
all_mappings.update(MAPPING_Y)

mypy 返回以下错误(python 3.4):

t.py:30: error: Argument 1 to "update" of "dict" has incompatible type Dict[type, str]; expected Mapping[Type[A], str]
t.py:31: error: Argument 1 to "update" of "dict" has incompatible type Dict[type, str]; expected Mapping[Type[A], str]

我不明白如何指定我想要 A 的子类作为字典键。如何声明类型?

【问题讨论】:

  • @JacquesGaudin OP 正在使用 mypy module 进行类型检查。它确实会产生错误。
  • @RickTeachey 谢谢,我没有意识到这一点。

标签: python type-hinting mypy


【解决方案1】:

我可能不明白typingmypy 模块是如何工作的,但这里似乎存在某种错误。如果我这样做(示例改编自docstyping.Type 部分):

import typing

class User(): pass
class BasicUser(User): pass

def make_new(u: typing.Type[User]) -> User:
    return u()

x = make_new(BasicUser)

没有mypy 错误。如果我这样做:

import typing

class A():
    pass

MAPPING_X = {
    A: 'a',
}
all_mappings = {}  # type: typing.Dict[typing.Type[A], str]
all_mappings.update(MAPPING_X)

也没有错误。但是,这确实会产生mypy 错误:

import typing

class A():
    pass

class B(A):
    pass

MAPPING_X = {
    A: 'a',
    B: 'b',
}

all_mappings = {}  # type: typing.Dict[typing.Type[A], str]
all_mappings.update(MAPPING_X)

根据我对文档的理解,这个错误应该不会发生。

【讨论】:

    【解决方案2】:

    看起来您这样做是正确的,但需要先声明MAPPING_XMAPPING_Y 的类型。这解决了问题。

    # -*- coding: utf-8 -*-
    import typing
    
    class A(object):
        pass
    
    class B(A):
        pass
    
    class C(A):
        pass
    
    class D(A):
        pass
    
    class E(A):
        pass
    
    MAPPING_X = {}  # type: typing.Dict[typing.Type[A], str]
    MAPPING_Y = {}  # type: typing.Dict[typing.Type[A], str]
    
    MAPPING_X = {
        B: 'b',
        C: 'c',
    }
    MAPPING_Y = {
        D: 'd',
        E: 'e',
    }
    
    all_mappings = {}  # type: typing.Dict[typing.Type[A], str]
    all_mappings.update(MAPPING_X)
    all_mappings.update(MAPPING_Y)
    

    没有mypy 错误。

    但是,在我看来,您编写的代码应该可以工作,这是错误的症状。

    【讨论】:

      猜你喜欢
      • 2022-01-06
      • 2013-05-02
      • 2019-02-16
      • 1970-01-01
      • 2017-08-12
      • 2021-01-20
      • 1970-01-01
      • 2017-06-10
      • 1970-01-01
      相关资源
      最近更新 更多