Добавьте подсказку типа к вызову метода Dynami c в Python - PullRequest
1 голос
/ 31 марта 2020

Как набирать метод, вызываемый динамически?

Пример:


class ABBase:
    def get_processor_func(self, name: str): # ?? How to type return ?
        func_name = f"process_{name}"
        return getattr(self, func_name, None)

    def process_all(self):
        for p in ['1', '2', '3']:
            func = self.get_processor_func(p)
            if func:
                print(func())

class ProcessA(ABBase):

    def process_1(self) -> int:
        return 111

    def process_2(self) -> int:
        return 222


class ProcessB(ABBase):

    def process_1(self) -> int:
        return 111

    def process_3(self) -> int:
        return 333


a = ProcessA()
a.process_all()
print('----')
b = ProcessB()
b.process_all()

Можно ли добавить аннотацию типа к этой конструкции? Как набрать get_processor_func метод или целый класс? Python 3.8 мне достаточно.

1 Ответ

3 голосов
/ 31 марта 2020

Поскольку все возможные методы имеют одинаковый тип, вы можете указать этот тип статически.

<b>from typing import Callable, Optional</b>


class ABBase:
    def get_processor_func(self, name: str) <b>-> Optional[Callable[[],int]]</b>:
        func_name = f"process_{name}"
        return getattr(self, func_name, None)

    def process_all(self):
        for p in ['1', '2', '3']:
            func = self.get_processor_func(p)
            if func:
                print(func())

Optional учитывает вероятность того, что возвращаемое значение будет None, а не соответствующий вызываемый .

Если подпись может отличаться, вы можете использовать ... вместо списка типов аргументов: Callable[...,int].

Если тип возвращаемого значения может изменяться, вы ничего не можете сделать полезнее, чем указывать typing.Any.

В худшем случае, когда аргументы и тип возвращаемого значения могут различаться, лучше всего сказать, что get_process_func возвращает вызываемый объект.

def get_processor_func(self, name: str) -> Optional[Callable]
...