[英]How do you overload python class method based on Enum type
I am trying to create a python method for a class which uses overload typing decorator.我正在尝试为使用重载类型装饰器的类创建一个 python 方法。 I want the method to be overloaded based on the Enum type being passed.
我希望根据传递的 Enum 类型重载该方法。 For example,
例如,
class GetPortType(enum.Enum):
DIFF_1: "Diff1"
DIFF_2: "Diff2"
SAME_1: "Same1"
SAME_2: "Same2"
class Port:
...
@typing.overload
def get_port_on_type(self, type: GetPortType.DIFF_1, num: int, skip: Optional[List]):
statement1
statement2
return [values]
@typing.overload
def get_port_on_type(self, type: GetPortType.DIFF_2, num: int, skip: Optional[List]):
statement3
statement4
return [values]
@typing.overload
def get_port_on_type(self, type: GetPortType.SAME_1, num: int, skip: Optional[List]):
statement1
statement3
return [values]
@typing.overload
def get_port_on_type(self, type: GetPortType.SAME_2, num: int, skip: Optional[List]):
statement2
statement4
return [values]
How do I achieve this?我如何实现这一目标? Should I create a "def __ new __(self, value):" method for the Enum and return type for all these cases?
我是否应该为 Enum 创建一个“def __ new __(self, value):”方法并为所有这些情况返回类型?
EDIT: I was wondering if there was something we could do with Metaclass and like value return type maybe?编辑:我想知道我们是否可以用 Metaclass 做一些事情,比如值返回类型? Which could be a property of this metaclass?
哪个可能是这个元类的属性?
@property
def type(self):
return type(self.value)
""" changing the type annotation """
type: GetPortType.SAME_2.type
It appears you've misunderstood what typing.overload
does.看来您误解了
typing.overload
作用。 It does not let you define different versions of your code that get run in different situations.它不允许您定义在不同情况下运行的不同版本的代码。 Rather, it's used for type hinting, to indicate that several combinations of types are supported by a single implementation.
相反,它用于类型提示,以指示单个实现支持多种类型组合。 None of the overload definitions of the function will ever be run, they only add better type hinting to the real version of the function that comes later.
该函数的任何重载定义都不会被运行,它们只会向稍后出现的函数的真实版本添加更好的类型提示。
Here's an example given in the documentation :这是 文档中给出的示例:
@overload
def process(response: None) -> None:
...
@overload
def process(response: int) -> tuple[int, str]:
...
@overload
def process(response: bytes) -> str:
...
def process(response):
<actual implementation>
Note that the ...
elipsis literal is something you might actually put in this code, it's not standing in for something only left out for the documentation.请注意,
...
elipsis 文字是您可能实际放入此代码中的内容,它并不代表文档中仅遗漏的内容。 There's no body needed in those @overload
decorated functions, since they never run.在那些
@overload
装饰函数中不需要主体,因为它们从不运行。 The ...
literal seems to have emerged among type-hinting aficionados as a preferred body for function stubs, rather than pass
(which at least used to be the preferred "do nothing" body for a function). ...
字面量似乎已经出现在类型提示爱好者中,作为函数存根的首选主体,而不是pass
(至少曾经是函数的首选“什么都不做”主体)。
If you actually need a decorator that will run a different version of a function depending on an argument's type, you might be able to use functools.singledispatch
.如果您确实需要一个装饰器来根据参数的类型运行不同版本的函数,您可以使用
functools.singledispatch
。 But it only dispatches on actual types, not literal values like you're wanting (eg specific instances of an Enum
).但它只发送实际类型,而不是您想要的字面值(例如
Enum
特定实例)。
The simple solution to your problem is just to write a set of if
/ elif
/ else
blocks to separate out the calls once you're inside the function:解决您的问题的简单方法是编写一组
if
/ elif
/ else
块,以便在您进入函数后将调用分开:
def get_port_on_type(self, type: GetPortType, num: int, skip: Optional[List]):
if type == GetPortType.DIFF_1:
do_stuff_1()
elif type == GetPortType.DIFF_2:
do_stuff_2()
elif type == GetPortType.SAME_1:
do_stuff_3()
else: # type == GetPortType.SAME_2:
do_stuff_4()
Starting in Python 3.10, you can use the new match
and case
statements to do essentially the same thing as the chain of if
/ elif
/ else
code above, with a very slightly nicer syntax, but I'm still using 3.9 and I don't feel confident in writing an example for you that I can't test (see PEP 636 for a tutorial on the new statement types).从 Python 3.10 开始,您可以使用新的
match
和case
语句来做与上面的if
/ elif
/ else
代码链基本相同的事情,语法稍微好一些,但我仍在使用 3.9 而我不我有信心为您编写一个我无法测试的示例(有关新语句类型的教程,请参阅PEP 636 )。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.