python - python相当于c# where T : new()
问题描述
python中有没有办法将泛型类型限制为可以实例化的类型?
我正在寻找与 C# 的等价物
where T : new()
我已经在使用如下类型提示
T = TypeVar("T", bound=Button)
我想知道是否有类似的东西
T = TypeVar("T", bound=Button,new())
例如,假设 Button 是一个抽象类 (ABC),此代码应创建一个由 Button 的任何子类型组成的菜单
class Button(ABC):
def __init__(self) -> None:
self._name = ""
@abstractmethod
def show(self) -> None:
pass
def set_name(self, value:str) -> None:
self._name = value
class SquareButton(Button):
def show(self) -> None:
print("[",self._name,"]")
class CircleButton(Button):
def show(self) -> None:
print("(",self._name,")")
T = TypeVar("T", bound=Button) # restricting type here
class MenuBuilder:
def build(self,class_type: Type[T]) -> None:
pb1: Button = class_type()
pb2: Button = class_type()
pb3: Button = class_type()
pb1.set_name("button1")
pb2.set_name("button2")
pb3.set_name("button3")
pb1.show(); pb2.show(); pb3.show()
#main
mb: MenuBuilder = MenuBuilder()
mb.build(Button) # fails at run time - I want a pre-run error here
mb.build(CircleButton) # OK
就目前而言,它允许使用抽象类型 Button 调用该方法,当我尝试创建它的实例时,该方法在运行时失败。
我正在使用 python 3.8.1 和带有 pylance 的 VS Code
编辑:答案之一建议通过协议替换泛型以确保实现按钮功能。虽然这会阻止发送抽象类,但它允许发送不继承自 Button 的类。我正在寻找执行这两个限制的方法。
解决方案
我不熟悉这个话题,但Protocol
可能是去这里的方式。
from typing import Protocol
class Button(Protocol):
def show(self) -> None:
...
def set_name(self, value: str) -> None:
...
class BaseButton(object):
def __init__(self) -> None:
self._name = ""
def set_name(self, value:str) -> None:
self._name = value
class SquareButton(BaseButton):
def show(self) -> None:
print("[",self._name,"]")
class CircleButton(BaseButton):
def show(self) -> None:
print("(",self._name,")")
class MenuBuilder:
def build(self, class_type: Type[Button]) -> None:
pb1: Button = class_type()
pb2: Button = class_type()
pb3: Button = class_type()
pb1.set_name("button1")
pb2.set_name("button2")
pb3.set_name("button3")
pb1.show()
pb2.show()
pb3.show()
推荐阅读
- react-native - 在反应本机应用程序中呈现大型列表的问题
- javascript - 使用 react-player API 导致无法在控制台中的“DOMWindow”错误上执行“postMessage”?
- python - 如何在 Django 中创建一个模型的对象,同时创建另一个不同的模型?
- php - Laravel 7:读取单个资源不起作用
- ruby-on-rails - 如何测试具有早期回报的haml部分?
- jquery - Jquery 无法更改路线(Svelte,Sapper)
- python - Discord.py 查找谁对消息做出了反应
- ios - 具有 RxSwift/RxDataSources 的表格视图单元格中的高性能多个水平集合视图
- javascript - 反应 onChange 不更新状态
- node.js - 如何在写入时使用 sheetjs 或 exceljs 展平/重新编译 Excel 电子表格