简体   繁体   English

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

[英]Python type hints - specify key, value type for dict subclass

Say I have 说我有

class A(dict): pass

Is there any way to specify the type of the key and values of A ? 有什么办法指定键的类型和A的值? Can it be done in a way that the types are inherited - so class B(A) would inherit the type values for, say, key and would be able to override the type of value ? 是否可以通过继承类型的方式来完成-因此class B(A)可以继承键的类型值,并且可以覆盖值的类型?

Ideally this would be done via the type hints introduced in pep-0484 - but note I am on python 2 so I would need a solution with type comments. 理想情况下,这可以通过pep-0484中引入的类型提示来完成-但请注意,我使用的是python 2,因此我需要一个带有类型注释的解决方案。 If however this is not possible a solution involving metaclasses or any other hack would be acceptable. 但是,如果这不可能,涉及元类或任何其他黑客的解决方案将是可以接受的。

All type interactions with your class go through methods, so annotate those methods. 与类的所有类型交互都通过方法进行,因此请注释这些方法。 A.__setitem__(self, key, value): is called for setting a key-value pair and can be annotated to indicate the types expected. A.__setitem__(self, key, value):用于设置键-值对,可以对其进行注释以指示期望的类型。

Any valid PEP 484 annotation would do here, including type comments if you need Python 2 compatibility. 任何有效的PEP 484注释都可以在此处执行,如果需要Python 2兼容性,则包括类型注释。

Those annotations would be inherited to B unless B overrides the methods. 除非B覆盖方法,否则这些注释将继承给B

Elaborating on @MartijnPieters answer (I am using Pycharm 5.0.4 so behavior below may be due to the standard or to an IDE bug/feature) 详细说明@MartijnPieters的答案 (我使用的是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

So one needs to override all methods (key value type info is local to the individual methods). 因此,需要覆盖所有方法(键值类型信息对于单个方法而言是本地的)。 IOW, unlike the case for parameters or attributes etc where one can do: IOW,与参数或属性等可以执行的情况不同:

class A(object):

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

this is a NOOP: 这是一个NOOP:

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

Moreover there seems to be no way to be able to specify the types as class variables which could be readily overridden in subclasses. 而且,似乎没有办法将类型指定为可以在子类中轻易覆盖的类变量。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM