在键入时使用MyPy.DefaultDict具有固定的出厂功能



我想这样做:

from functools import partial
from typing import DefaultDict
def five() -> int:
return 5  # whatever.
MyDefaultDict = partial(DefaultDict[str, int], five)
my_mapping: MyDefaultDict = MyDefaultDict(x=4)
print(my_mapping['x'])
print(my_mapping['y'])
  • 新的类型/类的东西MyDefaultDict声明一次,并有一个单一的名称。
  • MyDefaultDict可以像一个类构造函数一样使用,它的签名与dict相同,唯一的区别是你得到的是一个defaultdictfive作为它的工厂。
  • MyPy应该理解MyDefaultDict相同(或者最好是的子类)DefaultDict[str, int]。这是上面代码中不能工作的部分。
  • 对于我当前的使用来说是不必要的,但在一般情况下是很好的:MyDefaultDict实际上应该具有类属性(例如。静态方法)继承自defaultdict

partial不合适并不奇怪。一般来说,partial与MyPy的关系很差,而在最好的情况下将被理解为返回某种Callable,这对于my_mapping来说不是一个明智的类型。(实际报告的故障为"scratch.py:9: error: Variable "scratch.MyDefaultDict" is not valid as a type"。)

许多其他的事情似乎可以工作,但我还没能让他们:

子类和重写__init__

class MyDefaultDict(DefaultDict[str, int]):
def __init__(self, *args, **kwargs):
DefaultDict[str, int].__init__(self, five, *args, **kwargs)

MyPy。

文件"scratch.py",第9行,在__init__
DefaultDict[str, int].__init__(self, five, *args, **kwargs)
TypeError:__init__()得到一个意外的关键字参数'x'

子类和重写__new__

class MyDefaultDict(DefaultDict[str, int]):
def __new__(cls, *args, **kwargs):
return super().__new__(cls, five, *args, **kwargs)

MyPy。
"KeyError: 'y'";未使用工厂功能

partial包裹起来,使其看起来像一个类型

我尝试了type与三个参数,typing.NewTypetypes.new_class。据我所知,这不是他们打算解决的问题。

我简单地研究了一下元类,并没有看到它们如何帮助解决这个问题。

我正在使用python 3.8,但其他版本的答案可能是可行的。

有谁知道这样做的正确方法吗?

在写上面的时候,我意识到覆盖__init__的不同方式会产生不同的结果。

这个也不能用:

class MyDefaultDict(DefaultDict[str, int]):
def __init__(self, *args, **kwargs):
super().__init__(self, five, *args, **kwargs)

File "scratch.py",第9行,__init__
super().__init__(self, five, *args, **kwargs)
TypeError:第一个参数必须是可调用的或None

这个工作;理解为什么:会很好

class MyDefaultDict(DefaultDict[str, int]):
def __init__(self, *args, **kwargs):
super().__init__(five, *args, **kwargs)

最新更新