为了进行类型检查而对NamedTuple进行子类化的一种方法

问题描述:

我有几个共享某些字段的namedtuples。我有一个函数接受这些元组,并保证只与共享字段交互。我想在mypy中检查这样的代码。为了进行类型检查而对NamedTuple进行子类化的一种方法

代码的一个例子是:

from typing import NamedTuple 

class Base(NamedTuple): 
    x: int 
    y: int 


class BaseExtended(NamedTuple): 
    x: int 
    y: int 
    z: str 

def DoSomething(tuple: Base): 
    return tuple.x + tuple.y 

base = Base(3, 4) 
base_extended = BaseExtended(5, 6, 'foo') 

DoSomething(base) 
DoSomething(base_extended) 

当我在此代码运行mypy我得到一个可预见的错误:

mypy_example.py:20: error: Argument 1 to "DoSomething" has incompatible type "BaseExtended"; expected "Base"

有没有办法来构建我的代码,并保持mypy类型检查?我无法从基本继承BaseExtended,因为有一个在NamedTuple继承实现中的错误:

https://github.com/python/typing/issues/427

我不想用一个丑陋的“联盟[基地,BaseExtended]”要么,因为这打破了我尝试类型检查列表,因为“列表[联盟[基地,BaseExtended]”不等于“列表[BaseExtended]”由于有关变量/协变类型的一些mypy法宝:

https://github.com/python/mypy/issues/3351

我应该只是放弃这个想法?

PEP 544提出了一个类型系统的扩展,将允许结构分类(静态鸭子打字)。另外,运行时实现typing.NamedTuple将很快得到改进,可能在6月底的Python 3.6.2中(这也将通过PyPI上的typing回溯)。

+0

谢谢。我想你不知道我可以使用的任何优雅的解决方法,直到3.6.2?如果是这种情况,我会接受答案并继续前进。 – wuzwm

+1

@wuzwm不,不幸的是我不知道。 – ivanl