我遇到按钮在创建时执行'命令的问题。为了阻止这种情况,我有一个可以阻止这种行为的功能
这是在创建按钮时可以调用函数而不执行的函数。通常它工作正常,但有一些功能似乎随机拒绝任何输入!这是代码:
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
似乎是完全随机的,哪些问题被接受,哪些不被接受。我真的很绝望,因为写这个类的同义词花了很多时间,我用args
和kwds
的数量来调整它们,然后就可以了。但是现在我已经到了一个我不知道将会传递多少args的点,所以这将不再适用。
问题:
答案 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
模块。这样,您必须在项目中管理的代码更少。