调用函数时如何丢弃多余的参数



背景

我正在开发PyQt应用程序,并添加了以下调试装饰器:

def debug_decorator(func):
@functools.wraps(func)
def wrapper_func(*args, **kwargs):
logging.debug(f"Calling {func.__name__}")
ret_val = func(*args, **kwargs)
logging.debug(f"{func.__name__} returned {ret_val!r}")
return ret_val
return wrapper_func

除其他外,我将其用于点击处理程序函数,例如:

self.share_qpb = QtWidgets.QPushButton("Share")
self.share_qpb.clicked.connect(self.on_share_clicked)
[...]
@debug_decorator
def on_share_clicked(self):

如果我运行此代码,当单击共享按钮时,我会得到以下错误:

TypeError: on_share_clicked() takes 1 positional argument but 2 were given

原因是Qt/PyQt中的clicked信号发送按钮(文档)的检查状态

当我用调试装饰器装饰函数时,这只是一个问题,而不是其他问题(我想额外的参数在某个地方被丢弃了)

问题

在不必为每个clicked信号处理程序添加参数的情况下,如何使调试装饰器工作

(我想找到一种解决方案,既适用于参数匹配的情况,也适用于有一个额外参数的情况)


我正在运行Python 3.8和PyQt 5.15

我通过检查len(args)提供的参数数量是否大于装饰函数接受func.__code__.co_argcount的参数数量来解决这个问题

我还检查修饰函数的名称是否包含字符串";点击";因为我已经养成了将其作为点击处理程序函数名称的一部分的习惯。这样做的优点是,如果用太多参数调用另一个修饰函数,我们将(像往常一样)得到一个错误

def debug_decorator(func):
@functools.wraps(func)
def wrapper_func(*args, **kwargs):
logging.debug(f"=== {func.__name__} was called")
func_arg_count_int = func.__code__.co_argcount
func_name_str = func.__name__
if len(args) > func_arg_count_int and "clicked" in func_name_str:  # <----
args = args[:-1]
ret_val = func(*args, **kwargs)
logging.debug(f"=== {func.__name__} returned {ret_val!r}")
return ret_val
return wrapper_func

感谢@ekhumulko帮我解决这个问题!

相关内容

最新更新