使函数可调用的函数无法正常工作

Function to make functions callable doesn't work properly

我遇到了按钮在创建时执行其命令的问题。为了阻止这种情况,我有一个函数可以阻止这种行为

这个函数在创建我的按钮时无需执行即可调用函数。通常它工作正常,但对于某些功能,它似乎随机拒绝任何输入!这是代码:

class Callable(object):
    def __init__(self, func, *args, **kwds):
        self.func = func
        self.args = args
        self.kwds = kwds

    def __call__(self, *args, **kwds):
         return self.func(self.args)

    def __str__(self):
        return self.func.__name

似乎完全随机地接受了哪些问题,哪些不接受了。我真的很绝望,因为写这种class的一种同义词需要很多时间,我将它们与argskwds的数字适配,然后就可以了.但现在我已经到了不知道要传递多少参数的地步,所以这将不再有效。

问题:

我相信这就是您要找的:

class Callable(object):
    def __init__(self, func, *args, **kwds):
        self.func = func
        self.args = args
        self.kwds = kwds

    def __call__(self, *args, **kwds):
         return self.func(*self.args, *args, **self.kwds, **kwds)

    def __str__(self):
        return self.func.__name

您需要使用 * 运算符将其解包,并使用 ** 作为关键字参数。这样你就可以传递你的变量和函数的调用变量。

更新:

对于早于 3.5 的 python 版本,这将有效:

class Callable(object):
    def __init__(self, func, *args, **kwds):
        self.func = func
        self.args = args
        self.kwds = kwds

    def __call__(self, *args, **kwds):
        args = self.args + args
        kwargs = kwds.copy()
        kwargs.update(self.kwds)
        return self.func(*args, **kwargs)

    def __str__(self):
        return self.func.__name

使用此解决方案,您将首先给出 __init__ 获取的变量,然后传递给 __call__ 的变量。

您的 class 用于为 tkinter 回调提供额外的上下文,以便回调实际上可以做一些有用的事情。除了在调用函数时需要解压缩原始 args 和 kwds 之外,您几乎是正确的。另外,不要在 __call__ 中包含任何参数,因为您不接受任何参数。

class Callable(object):
    def __init__(self, func, *args, **kwds):
        self.func = func
        self.args = args
        self.kwds = kwds

    def __call__(self):
         return self.func(*self.args, **self.kwargs)

    def __str__(self):
        return self.func.__name


def some_callback(a, b, c=None):
    print(a,b,c)

Button(text="Do not press", 
    command=Callable(some_callback, 1, 2, 3))

这也可以在没有 class 的情况下使用 lambda 来完成

def some_callback(a, b, c=None):
    print(a,b,c)

Button(text="Do not press", 
    command=lambda: some_callback(1, 2, 3))

请考虑使用以下class。它允许您在实例创建或实例调用(创建新实例或调用它)时指定位置参数和关键字参数。由于如果两次指定任一类型的参数意味着什么是不明确的,class 拒绝猜测预期的顺序或优先级并提出 RuntimeError 以防止未定义的行为。此外,如果您的函数或其他可调用对象没有 __name__ 属性,__str__ 方法应该仍然有效。

class Callable:

    def __init__(self, function, *args, **kwargs):
        self.__function, self.__args, self.__kwargs = function, args, kwargs

    def __call__(self, *args, **kwargs):
        if (args or kwargs) and (self.__args or self.__kwargs):
            raise RuntimeError('multiple args and kwargs are not supported')
        if args or kwargs:
            return self.__function(*args, **kwargs)
        return self.__function(*self.__args, **self.__kwargs)

    def __str__(self):
        return getattr(self.__function, '__name__', 'function')

您可能还想查看 functools.partial 以了解具有非常相似行为的明确定义的对象。您可以避免定义自己的 Callable class 并改用 functools 模块。这样,您在项目中需要管理的代码就会更少。