Pythoni c способ использования enum для выбора и запуска определенного подметода? - PullRequest
1 голос
/ 04 августа 2020

У меня есть функция, которая будет вызываться конечным пользователем, и эта функция принимает аргумент int от 1 до 3 включительно. В зависимости от int, я хочу, чтобы функция запускала отдельный вспомогательный метод. Я обычно делаю это с операторами if, как показано ниже, но я ищу более чистый / более pythoni c способ сделать это, используя Enum.

def user_function(user_arg: int) -> float:
    if user_arg == 1:
        return sub_method_1()
    elif user_arg == 2:
        return sub_method_2()
    elif user_arg == 3:
        return sub_mthod_3()
    print(f"Error: user_arg must be in [1,2,3]. Supplied argument: {user_arg}")

В идеале функция должна выглядеть примерно так

from enum import Enum

class UserMethod(Enum):
    FIRST_METHOD = 1
    SECOND_METHOD = 2
    THIRD_METHOD = 3

   def choose_method(self):
       #... use enum to choose from the 3 sub methods ...

# This function is now much cleaner
def user_function(user_arg: int) -> float:
    um = UserMethod(user_arg)
    return um.choose_method()

Я не понимаю, как использовать Enum, чтобы это сделать, или это даже лучший способ?

Ответы [ 4 ]

1 голос
/ 04 августа 2020

Самый чистый способ сделать это на данный момент - использовать aenum библиотеку 1 :

from aenum import Enum

class UserMethod(Enum):
    #
    _init_ = 'value method'
    #
    def __call__(self, *args, **kwds):
        return self.method(*args, **kwds)
    #
    def first(blah):
        return blah
    #
    def second(spam=2):
        return spam
    #
    def third(this, that):
        return this, that
    #
    FIRST_METHOD = 1, first
    SECOND_METHOD = 2, second
    THIRD_METHOD = 3, third

Каждый метод хранится в самом члене перечисления и вызывает член передает вызов соответствующей функции.

--> list(UserMethod)
[<UserMethod.FIRST_METHOD: 1>, <UserMethod.SECOND_METHOD: 2>, 
<UserMethod.THIRD_METHOD: 3>]

--> UserMethod.THIRD_METHOD("hello", "world")
('hello', 'world')

и

# This function is now much cleaner
def user_function(user_arg: int) -> float:
    return UserMethod(user_arg).method

1 Раскрытие: я являюсь автором Python stdlib Enum, enum34 backport и Advanced Перечисление (aenum) библиотека.

0 голосов
/ 04 августа 2020

В вашем методе choose_method вы можете получить выбранный Enum, используя self, например:

def choose_method(self):
    print(self)  # Will print the Enum atributte

С помощью этого вы можете создать dict, указывающий на другие методы;

def choose_method(self):
    methods = {
        UserMethod.FIRST_METHOD: self.sub_method_one,
        UserMethod.SECOND_METHOD: self.sub_method_two,
        UserMethod.THIRD_METHOD: self.sub_method_three,
    }

    return methods.get(self)()

def sub_method_one(self):
    print("Method 1")

def sub_method_two(self):
    print("Method 2")

def sub_method_three(self):
    print("Method 3")
0 голосов
/ 04 августа 2020

Использование перечислений не было бы моим первым импульсом - я бы сказал, что pythoni c не будет использовать его в этом сценарии, и я не думаю, что вы можете оправдать использование перечисления. Вероятно, вы просто захотите сопоставить ввод пользователя с функцией с помощью словаря:

def first_function():
    print("In first!")

def second_function():
    print("In second!")

def third_function():
    print("In third!")


functions = {
    1: first_function,
    2: second_function,
    3: third_function
}

functions[1]()

Вывод:

In first!
>>> 

В этом случае ключи являются целыми числами, но они могут тоже быть струнами - или чем-то еще. Я просто жестко запрограммировал 1 в functions[1](), но вы поняли идею.

0 голосов
/ 04 августа 2020

Можно сделать еще проще (то есть не полагаясь на Python Enums):

def user_function(user_arg: int) -> float:
    assert user_arg in [1,2,3], \
        f"Error: user_arg must be in [1,2,3]. Supplied argument: {user_arg}"

    return [sum_method_1, 
            sub_method_2,
            sub_method_3][user_arg-1]()
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...