2016-04-23 160 views
0

说我有Python类型提示 - 指定键,值类型的字典子

class A(dict): pass 

有什么方法来指定的键和值的类型?是否可以通过继承类型来完成 - 因此class B(A)会继承key的类型值,并且能够覆盖值的类型?

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

+0

你是什么意思*“type comments”*?你真的想要执行这个类型,还是仅仅记录它? – jonrsharpe

+0

@jonrsharpe:请参阅[PEP 484 *类型注释*](https://www.python.org/dev/peps/pep-0484/#type-comments) –

+0

@MartijnPieters啊谢谢,我想知道OP是指文档或东西。 – jonrsharpe

回答

2

与你的类的所有类型的交互通过方法,所以注释这些方法。调用A.__setitem__(self, key, value):来设置键值对,并可以注释以指示预期的类型。

任何有效的PEP 484注释都会在这里执行,包括类型注释,如果您需要Python 2兼容性。

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

+0

非常感谢 - 类型信息是否会以其他方法传播,还是必须对它们进行注释? –

+0

@Mr_and_Mrs_D:子类化时,你必须注释所有方法,是的,因为'dict'类型本身没有注释。 –

+0

查看我的编辑 - 所以最后没有神奇的方式来指定键/值类型作为类变量,并将此信息传播到所有内置方法? –

0

在阐述@MartijnPieters answer(我用Pycharm 5.0.4所以下面的行为可能是由于标准或到IDE的bug /功能)

_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] 

这是一个空操作:

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

而且似乎没有办法能够指定类型作为可以在子类中轻易覆盖的类变量。