我有几个命名的,
共享一些字段。我有一个接受这些元组的函数,并保证只与共享字段交互。我想在mypy中键入检查此类代码。
代码的一个示例是:
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:错误:“DoSomething”的参数1具有不兼容的类型“base extended”;预期的“基数”
有没有办法构造我的代码并保持我的py类型检查?我无法从< code>Base继承< code>BaseExtended,因为在< code>NamedTuple继承实现中有一个错误。
我也不想使用丑陋的联合[基数,基数扩展]
,因为当我尝试键入检查列表
时,这会中断,因为列表[联合[基,基扩展]]
不等于列表[基扩展]
,因为关于变体/协变类型的一些神秘的魔力。
我应该放弃这个想法吗?
PEP 544建议对类型系统进行扩展,以允许结构子类型化(静态duck类型化)。此外,类型的运行时实现。NamedTuple
将很快得到改进,可能在6月底的Python 3.6.2中(这也将通过在PyPI上键入
构造命名元组的方式继承了< code >类型。NamedTuple类尚不可能。您必须编写自己的元类来扩展< code >类型。NamedTupleMeta类来实现子类化,即使这样,由< code > collections . named tuple()生成的类也不是为扩展而构建的。
相反,您希望使用新的dataclasses
模块来定义类并实现继承:
from dataclasses import dataclass
@dataclass(frozen=True)
class Base:
x: int
y: int
@dataclass(frozen=True)
class BaseExtended(Base):
z: str
该模块在Python 3.7中是新的,但您可以pip安装数据类
Python 3.6上的反向端口。
上面用< code>x和< code>y属性定义了两个不可变的类,其中< code>BaseExtended类增加了一个属性。< code>BaseExtended是< code>Base的完整子类,因此出于键入目的,它符合< code>DoSomething()函数的要求。
这些类不是完整命名的元组,因为它们没有长度或不支持索引,但这是通过创建继承自collections.abc.Sequence
的基本类来添加的,添加了两个方法来按索引访问字段。如果您将order=True
添加到@dataclass()
装饰器,那么您的实例就可以像(命名的)元组一样完全排序:
from collections.abc import Sequence
from dataclasses import dataclass, fields
class DataclassSequence(Sequence):
# make a dataclass tuple-like by accessing fields by index
def __getitem__(self, i):
return getattr(self, fields(self)[i].name)
def __len__(self):
return len(fields(self))
@dataclass(frozen=True, order=True)
class Base(DataclassSequence):
x: int
y: int
MyPy将很快明确支持< code > data classes ;在0.600版本中,您仍然会得到错误,因为它不能识别< code>dataclasses模块导入或生成了< code>__new__方法。
在Python 3.6及更早版本中,您还可以安装attrs
项目来实现相同的效果;使用attrs
,上面的序列基类如下所示:
from collections.abc import Sequence
import attr
class AttrsSequence(Sequence):
# make a dataclass tuple-like by accessing fields by index
def __getitem__(self, i):
return getattr(self, attr.fields(type(self))[i].name)
def __len__(self):
return len(attr.fields(type(self)))
@attr.s(frozen=True, auto_attribs=True)
class Base(AttrsSequence):
x: int
y: int
< code>dataclasses直接基于< code>attrs,其中< code>attrs提供了更多功能;mypy完全支持用< code>attrs生成的类。
问题内容: 我有几个共享一些字段的namedtuple。我有一个接受这些元组的函数,并保证仅与共享字段进行交互。我想在mypy中对此类代码进行类型检查。 该代码的示例为: 当我在此代码上运行mypy时,我得到一个可预测的错误: mypy_example.py:20:错误:“ DoSomething”的参数1具有不兼容的类型“ BaseExtended”;预期的“基础” 有没有办法构造我的代码并保持
问题内容: 如果我有字典,并且想检查一下,则可以将其作为一个块(非常好!),也可以使用方法作为默认值。 我想为做同样的事情。也就是说,如果尚未设置对象,我已经有要返回的对象,但这给了我类似的错误 AttributeError:’bool’对象没有属性’attribute’ 问题答案: 更直接的类似物比是。 (在哪里是可选的,如果未找到,则在no属性上引发异常。) 例如,您将通过。
如果按照“字节”->“短”->“int”->“长”->“浮点”->“双倍”的自动转换,那么输出应该打印“双倍”,对吗? (https://www.geeksforgeeks.org/type-conversion-java-examples/)
我如何确认通过props(例如)接收的反应元素在我的渲染方法中属于给定类型? 假设我有一个元素和一个元素。在的render方法中,我想查找传递的所有子项,并对s中的任何子项执行一些特殊的操作。 我确实找到了一个可行的实现,但只是在反复试验之后。请参阅下面的代码。(第15.4.2节) 我ist.jsx 名单我tem.jsx 所以,最后一个实现似乎可以工作,但是为什么第一个实现不能工作呢?我在reac
我试图使使用该类注册的任何元块中的子块只需要一个类来命名,也就是说,将它们命名为参数值,但不使用参数值。 虽然这是围绕一个API(Minecraft Forge)展开的,但我认为这是一个Java问题,所以我在这里快速解释一下我打算做什么。 元块由子块组成,子块是同一块的变体(例如,同一块,但仅纹理和名称发生变化)。每个子块都需要一个名称来标识它。这些名称以的形式列在类中,然后以(例如:,,等等),