python等价于c#其中T:new()

2024-05-19 14:32:23 发布

您现在位置:Python中文网/ 问答频道 /正文

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

现在,它允许使用抽象类型按钮调用该方法,当我尝试创建它的实例时,该按钮在运行时失败

我在pylance中使用Python3.8.1和VS代码


Tags: namebuildselfnone类型deftypeshow
1条回答
网友
1楼 · 发布于 2024-05-19 14:32:23

我不熟悉这个话题,但是Protocol可能是解决这个问题的方法

from typing import Protocol


class ButtonImpl(Protocol):
    def show(self) -> None:
        ...

    def set_name(self, value: str) -> None:
        ...


class Button(object):
    def __init__(self) -> None:
        self._name = ""

    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,")")


class MenuBuilder:
    def build(self, class_type: Type[ButtonImpl]) -> None:
        pb1: ButtonImpl = class_type()
        pb2: ButtonImpl = class_type()
        pb3: ButtonImpl = class_type()
        pb1.set_name("button1")
        pb2.set_name("button2")
        pb3.set_name("button3")
        pb1.show(); pb2.show(); pb3.show()

相关问题 更多 >