python中可继承的自定义类构造函数
Posted
技术标签:
【中文标题】python中可继承的自定义类构造函数【英文标题】:Inheritable custom class constructor in python 【发布时间】:2021-11-20 12:35:30 【问题描述】:如何实现在python中可继承的自定义构造函数(类方法)?
以下最小化的示例可能会提供一个想法:
from dataclasses import dataclass
from typing import Type, TypeVar
T = TypeVar("T")
@dataclass
class Parent:
something: int = 2
@classmethod
def from_float(cls: Type[T], something_as_float: float) -> T:
return Type[T](something=int(something_as_float))
@dataclass
class Child(Parent):
""" Should also be constructible via from_float
"""
assert isinstance(Parent.from_float(1.0), Parent)
assert isinstance(Child.from_float(1.0), Child)
mypy 不喜欢我从 from_float 返回时调用的构造函数。我不知道如何从类方法中引用类(Parent 或 Child)。
【问题讨论】:
你的意思是像一个实例工厂? 不确定...添加一个 C++ 模式以便我可以在 python 中实现一个 Rust 模式感觉就像我只是在给垃圾火添油:) 为什么不实现__new__
方法?
@dataclass 隐式添加了获取字段的构造函数(以及 __new__?),我不能打扰它。我正在尝试将 rust 启发的转换方法添加到一些相互继承的现有数据类中,并且我无法更改设计的 dataclasses-with-inheritance 部分。
Type[T]
不是构造函数; cls
是。
【参考方案1】:
将bound
参数传递给TypeVar
以指定该类型是Parent
的子类。这让 mypy 知道该类型具有 something
属性
创建实例时使用cls
而不是Type[T]
from dataclasses import dataclass
from typing import Type, TypeVar
T = TypeVar("T", bound='Parent')
@dataclass
class Parent:
something: int = 2
@classmethod
def from_float(cls: Type[T], something_as_float: float) -> T:
return cls(something=int(something_as_float))
@dataclass
class Child(Parent):
pass
assert isinstance(Parent.from_float(1.0), Parent)
assert isinstance(Child.from_float(1.0), Child)
【讨论】:
太棒了。谢谢!我可以在本地确认它在没有断言的情况下运行,并且还通过了 mypy! 您不能在其定义中引用一个类......并且转义为 cls: "Parent" 和 -> "Parent" 也没有帮助。我点击“自我的擦除类型“minimized_typing_puzzle.Parent”不是其类“Type [minimized_typing_puzzle.Parent]”的超类型,然后错误:“Parent”不可调用。 Iain 的解决方案有效,但如果您喜欢输入谜题,请随时保持线程继续运行。谢谢!以上是关于python中可继承的自定义类构造函数的主要内容,如果未能解决你的问题,请参考以下文章