Как объединить функции в классе в Python? - PullRequest
0 голосов
/ 30 мая 2018

У меня есть такой код.В моем исходном коде я хотел бы вызывать два или более методов при нажатии кнопки.

class MyApp(object):

    @staticmethod
    def combine_funcs(*funcs):
        def combined_func(*args, **kwargs):
            for f in funcs:
                f(*args, **kwargs)
        return combined_func

    def __init__(self):
        MyApp.combine_funcs(self.my_first_func, self.my_second_func)

    def my_first_func(self):
        print("First")

    def my_second_func(self):
        print("Second")


my_app = MyApp()

Когда я запускаю, это ничего не печатается.Почему?

Ответы [ 2 ]

0 голосов
/ 30 мая 2018

Метод не намного больше, чем член класса, который оказывается функцией.Суть в том, что когда он вызывается для объекта (a.func(x...)), объект автоматически добавляется в список аргументов, в результате чего фактический вызов A.func(a, x...).

может быть получен следующим образом:

class MyApp(object):
    # prepend with _ to "hide" the symbol
    def _combine_funcs(*funcs):      
        def combined_func(*args, **kwargs):
            for f in funcs:
                f(*args, **kwargs)
        return combined_func

    def my_first_func(self):
        print("First")

    def my_second_func(self):
        print("Second")

    # actually declares combined as a method of MyClass
    combined = _combine_funcs(my_first_func, my_second_func)

Использование:

>>> a = MyApp()
>>> a.combined()
First
Second

Но гораздо более понятным способом было бы использовать декоратор для этого в Python 3:

import inspect

def combine_funcs(*funcs):
    def outer(f):
        def combined_func(*args, **kwargs):    # combine a bunch of functions
            for f in funcs:
                x = f(*args, *kwargs)
            return x                           # returns return value of last one
        combined_func.__doc__ = f.__doc__      # copy docstring and signature
        combined_func.__signature__ = inspect.signature(f)
        return combined_func
    return outer

class MyApp(object):

    def my_first_func(self):
        print("First")

    def my_second_func(self):
        print("Second")

    @combine_funcs(my_first_func, my_second_func)
    def combined(self):
        """Combined function"""
        pass

decorator заменит тело, но сохранит строку документации и подпись исходной функции (в Python 3).Затем вы можете использовать его как обычно:

>>> a = MyApp()
>>> a.combined()
First
Second
>>> help(a.combined)
Help on method combined_func in module __main__:

combined_func() method of __main__.MyApp instance
    Combined function

>>> help(MyApp.combined)
Help on function combined_func in module __main__:

combined_func(self)
    Combined function
0 голосов
/ 30 мая 2018

Вы звоните combine_funcs, но функция в этом combined_func не вызывается.

Есть ли причина не упрощать до:

class MyApp(object):

    @staticmethod
    def combined_func(*args, **kwargs):
        for f in args:
            f()

    def __init__(self):
        MyApp.combined_func(self.my_first_func, self.my_second_func)

    def my_first_func(self):
        print("First")

    def my_second_func(self):
        print("Second")

my_app = MyApp()
...