Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/python-3.x/17.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 调用函数时如何丢弃多余的参数? 背景_Python_Python 3.x_Pyqt_Pyqt5 - Fatal编程技术网

Python 调用函数时如何丢弃多余的参数? 背景

Python 调用函数时如何丢弃多余的参数? 背景,python,python-3.x,pyqt,pyqt5,Python,Python 3.x,Pyqt,Pyqt5,我正在处理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"

我正在处理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
除此之外,我将其用于click handler函数,例如:

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中单击的
信号发送按钮的选中状态()

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

问题: 如何使调试装饰器工作,而不必为每个单击的
信号处理程序添加参数?

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



我正在运行Python3.8和PyQt 5.15,通过检查提供的
len(args)
的参数数是否大于修饰函数接受的
func.\uu code\uu.co\u argcount

我还检查修饰函数的名称是否包含字符串“clicked”,因为我习惯将其作为click处理函数名称的一部分。这样做的好处是,如果使用太多参数调用另一个修饰函数,我们将(像往常一样)得到一个错误

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
def debug_decorator(func):
@functools.wrapps(func)
def wrapper_func(*args,**kwargs):
debug(f“==={func.\uuuu name\uuuuuuuu}被调用”)
func\u arg\u count\u int=func.\u代码\u.co\u argcount
func\u name\u str=func.\u name__

如果len(args)>func_arg_count_int并在func_name_str中单击:#当直接调用修饰函数/方法(即,不通过连接信号)时,您希望发生什么?它还是应该丢弃多余的参数,还是像正常情况一样引发错误?如果是后者,则需要检测修饰后的函数/方法是否被信号调用。以一种完全通用的方式,这不是一件容易的事情,特别是当装饰程序必须处理任意可调用项时。@ekhumoro我想丢弃参数是可以的,如果这样可以更容易地找到问题的解决方案,您可以通过执行
args=args[:func.\ucode\uu.co\u argcount-1]
来丢弃额外的参数。然而,这将隐藏真正的bug,因此我显然不建议在调试工具中使用它。如果有一种通用的方法来检测插槽是由信号直接触发的,那么一个合适的解决方案是可能的。但我非常确定,目前在pyqt或pyside中都没有可靠的方法来实现这一点。