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

时间:2016-03-24 17:01:51

标签: python class python-3.x button callable

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

这是在创建按钮时可以调用函数而不执行的函数。通常它工作正常,但有一些功能似乎随机拒绝任何输入!这是代码:

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

似乎是完全随机的,哪些问题被接受,哪些不被接受。我真的很绝望,因为写这个类的同义词花了很多时间,我用argskwds的数量来调整它们,然后就可以了。但是现在我已经到了一个我不知道将会传递多少args的点,所以这将不再适用。

问题:

  • 为什么这个班不接受所有的功能呢?
  • 如何更改此行为?

3 个答案:

答案 0 :(得分:3)

我相信你正在寻找的东西:

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__

答案 1 :(得分:0)

您的类用于为tkinter回调提供额外的上下文,因此回调实际上可以做一些有用的事情。除了在调用函数时需要解压缩原始args和kwds之外,你几乎已经正确了。此外,请勿在{{1​​}}中包含任何参数,因为您不接受任何参数。

__call__

这也可以在没有班级的情况下完成,而不是使用lambdas

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

答案 2 :(得分:0)

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

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类,而是使用functools模块。这样,您必须在项目中管理的代码更少。