简体   繁体   English

你如何基于Enum类型重载python类方法

[英]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 开始,您可以使用新的matchcase语句来做与上面的if / elif / else代码链基本相同的事情,语法稍微好一些,但我仍在使用 3.9 而我不我有信心为您编写一个我无法测试的示例(有关新语句类型的教程,请参阅PEP 636 )。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 如何在python中重载插入符号(^)运算符 - How do you overload the caret (^) operator in python 如何在重载中正确键入提示内部变量 - How do you type hint inner variable properly in overload 如何根据参数类型重载 __init__ 方法? - How to overload __init__ method based on argument type? 您可以根据传递给构造函数的参数键入提示重载方法的返回类型吗? - Can you type hint overload a return type for a method based on an argument passed into the constructor? 在python中,如何根据返回类型重载返回/获取? - In python, how to overload return/get based on return type? 如何在 Python 中获得正确类型的 class - How do you get the correct type of class in Python 基于参数计数的Python方法重载? - Python method overload based on argument count? 你如何在 python 中创建一个类或函数,允许你创建具有特定特征的序列类型 - How do you create a class, or function in python that allows you to make a sequence type with specific characteristics Python:如何将Class function的参数类型指定为当前的ZA2F2ED4F8EBC2CBB4C21A9? - Python: How do you specify the parameter type of a Class function to the current class? 如何从Python中不同类的另一个类访问方法来编辑Kivy对象? - How do you access a method from another class from a different class in Python to edit a Kivy object?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM