Python 类型提示 - 为 dict 子类指定键、值类型

Posted

技术标签:

【中文标题】Python 类型提示 - 为 dict 子类指定键、值类型【英文标题】:Python type hints - specify key, value type for dict subclass 【发布时间】:2016-08-17 02:38:07 【问题描述】:

说我有

class A(dict): pass

有没有办法指定 A 的键和值的类型?是否可以以继承类型的方式完成 - 所以class B(A) 将继承类型值,例如,键并能够覆盖值的类型?

理想情况下,这将通过pep-0484 中引入的类型提示来完成 - 但请注意我在 python 2 上,所以我需要一个类型为 cmets 的解决方案。但是,如果这是不可能的,那么涉及元类或任何其他黑客的解决方案是可以接受的。

【问题讨论】:

"type cmets" 是什么意思?你真的想强制执行类型,还是只是记录它? @jonrsharpe:见PEP 484 Type Comments @MartijnPieters 啊谢谢,我想知道 OP 是指文档字符串还是什么。 【参考方案1】:

与您的类的所有类型交互都通过方法进行,因此请对这些方法进行注释。 A.__setitem__(self, key, value): 被调用来设置一个键值对并且可以被注解来指示期望的类型。

任何有效的 PEP 484 注释都可以在这里使用,包括类型 cmets 如果您需要 Python 2 兼容性。

除非 B 覆盖方法,否则这些注释将被继承到 B

【讨论】:

非常感谢 - 类型信息会在其他方法中传播,还是我必须全部注释? @Mr_and_Mrs_D: 子类化的时候你必须注解所有方法,是的,因为dict类型本身没有注解。 查看我的编辑 - 所以最终没有神奇的方法可以将键/值类型指定为类变量并将此信息传播到所有内置方法? @Mr_and_Mrs_D:你能为新问题创建一个新帖子吗?是的,这是相关的,因为您的新问题源于旧问题,但您的原始问题已得到解答。 @Mr_and_Mrs_D:不,据我所知,没有办法神奇地应用它。【参考方案2】:

详细说明@MartijnPieters answer(我使用的是 Pycharm 5.0.4,因此以下行为可能是由于标准或 IDE 错误/功能所致)

_key_type_global = unicode

class A(dict):

    _key_type = unicode

    def __setitem__(self, key, value):
        """A._key_type is not recognised, _key_type_global is
        :type key: _key_type_global
        :type value: int
        """
        super(A, self).__setitem__(key, value)

class B(A): pass


a = A()
a['str'] = 'uy' # expected type unicode got str instead
a[u'str'] = 'uy' # no warn (?)
a[u'str'] = 1 # no warn

val = a[u'str'] # Pycharm does not give any type info on value so I have to 
# define __getitem__ too

# type info is inherited
b = B()
b['str'] = 'uy' # expected type unicode got str instead
b[u'str'] = 'uy' # no warn (?)
b[u'str'] = 1 # no warn

因此需要覆盖所有方法(键值类型信息是各个方法的本地信息)。 IOW,不像参数或属性等可以做的情况:

class A(object):

    def __init__(self, dct):
        self.dct = dct # type : dict[unicode, int]

这是一个 NOOP:

class A(dict): # type dict[unicode, int]

此外,似乎无法将类型指定为可以在子类中轻松覆盖的类变量。

【讨论】:

以上是关于Python 类型提示 - 为 dict 子类指定键、值类型的主要内容,如果未能解决你的问题,请参考以下文章

为动态类型指定元类

python 继承机制(子类化内置类型)

指定函数返回类型为dict的KeysView

Python 覆盖子类中方法返回的类型提示,无需重新定义方法签名

第六章深入python的set和dict

键入具有多种键值类型的 Dict [重复]