使函数可调用的函数无法正常工作
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的一种同义词需要很多时间,我将它们与args
和kwds
的数字适配,然后就可以了.但现在我已经到了不知道要传递多少参数的地步,所以这将不再有效。
问题:
- 为什么这个 class 不接受所有函数?
- 如何改变这种行为?
我相信这就是您要找的:
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
模块。这样,您在项目中需要管理的代码就会更少。
我遇到了按钮在创建时执行其命令的问题。为了阻止这种情况,我有一个函数可以阻止这种行为
这个函数在创建我的按钮时无需执行即可调用函数。通常它工作正常,但对于某些功能,它似乎随机拒绝任何输入!这是代码:
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的一种同义词需要很多时间,我将它们与args
和kwds
的数字适配,然后就可以了.但现在我已经到了不知道要传递多少参数的地步,所以这将不再有效。
问题:
- 为什么这个 class 不接受所有函数?
- 如何改变这种行为?
我相信这就是您要找的:
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
模块。这样,您在项目中需要管理的代码就会更少。