【问题标题】:How to combine functions in a class in Python?如何在 Python 中的类中组合函数?
【发布时间】:2018-05-30 12:32:43
【问题描述】:

我有这样的代码。在我的原始代码中,我想在单击按钮时调用两个或多个方法。

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()

当我运行它时,什么都没有打印出来。为什么?

【问题讨论】:

  • 您只是在组合函数,而不是调用新组合的函数函数。
  • 好的,谢谢。我需要括号。但是,当我想在按下按钮时调用它们时self.ui.pushButton.clicked.connect(MyApp.combine_funcs(self.converter(), self.showMessage())) 是一样的吗?它们会立即被调用,而不是等待鼠标点击?
  • combine_funcs(self.converter(), ...)combine_funcs(self.my_first_func, ...) 不一样,现在是吗?
  • 好的,我的代码似乎有更多问题。 () 执行一个函数。这就是为什么我的 init 什么也没做。我现在明白了。第二个问题是当我在self.ui.pushButton.clicked.connect(MyApp.combine_funcs(self.converter, self.showMessage)) 中删除() 时,我收到错误converter() takes 1 positional argument but 2 were given。转换器函数只接受 self 参数。我要发送哪两个参数?
  • 当它最终被调用时,它正在被传递参数......

标签: python static-classes


【解决方案1】:

方法只不过是恰好是函数的类的成员。神奇之处在于,当在对象 (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

装饰器将替换正文,但将保留文档字符串和原始函数的签名(在 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

【讨论】:

    【解决方案2】:

    您正在调用 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()
    

    【讨论】:

      猜你喜欢
      • 2013-05-20
      • 1970-01-01
      • 1970-01-01
      • 2021-01-04
      • 2019-08-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多