在Python中使用loguru库捕获异常出现bug的修正方法
Published in:2024-05-16 |
Words: 865 | Reading time: 3min | reading:

在Python中使用loguru库捕获异常出现bug的修正方法

背景

Loguru is a library which aims to bring enjoyable logging in Python.

Did you ever feel lazy about configuring a logger and used print() instead?… I did, yet logging is fundamental to every application and eases the process of debugging. Using Loguru you have no excuse not to use logging from the start, this is as simple as from loguru import logger.

Also, this library is intended to make Python logging less painful by adding a bunch of useful functionalities that solve caveats of the standard loggers. Using logs in your application should be an automatism, Loguru tries to make it both pleasant and powerful.

bug描述

  • 当使用qt5槽函数调用某类中被@logger.catch包裹的方法时报如下异常:
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    2024-05-16 11:17:09.406 | ERROR    | __main__:ui_paint:27 - An error has been caught in function 'ui_paint', process 'MainProcess' (9856), thread 'MainThread' (9108):
    Traceback (most recent call last):

    File "C:\Users\Administrator\PycharmProjects\ss\src\run\ui_main.py", line 54, in <module>
    run_main_py()
    └ <function run_main_py at 0x0000027A3F4E9A60>

    File "C:\Users\Administrator\PycharmProjects\ss\src\run\ui_main.py", line 50, in run_main_py
    ui_paint()
    └ <function ui_paint at 0x0000027A3F4A09D0>

    > File "C:\Users\Administrator\PycharmProjects\ss\src\run\ui_main.py", line 27, in ui_paint
    app.exec_()
    │ └ <built-in method exec_>
    └ <PyQt5.QtWidgets.QApplication object at 0x0000027A3F4F3E50>

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

bug复现

  • 代码如下:

    class code

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    class MyClass(QWidget): 
    def __init__(self, parent=None):
    super(MyClass, self).__init__(parent)


    @logger.catch()
    def next_img(self):
    """
    跳转下一页
    :return:
    """
    # 你的代码逻辑
    pass

    调用代码

    1
    self.next_button.clicked.connect(self.next_img)

    运行上述代码,即可出现上述bug

解决方案

Qt (或者 PyQt、PySide 等 Qt 的 Python 绑定) 中,当你使用信号和槽机制(即 clicked.connect())时,槽函数(即你连接到的函数或方法)通常会接收一个额外的参数,这个参数代表了触发信号的发送者(sender)。因此,即使你的 next_img 方法在类定义中只接受一个参数(self),当它被用作一个槽时,Qt 会自动传递一个额外的参数,通常是发出信号的对象的引用。 为了解决这个 TypeError,你需要修改你的 next_img 方法,让它能够接受这个额外的参数。

修正代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
class MyClass(QWidget):  # 假设 MyClass 继承自 QWidget 或其他 Qt 控件
def __init__(self, parent=None):
super(MyClass, self).__init__(parent)
# 假设 next_button 是一个 QPushButton 的实例
self.next_button = QPushButton('Next', self)
self.next_button.clicked.connect(self.next_img)

@logger.catch()
def next_img(self, _=None): # 添加一个额外的参数 _ 来接收发送者
"""
跳转下一页
:return:
"""
# 你的代码逻辑
pass

修正思路

在这个例子中,next_img 方法现在接受一个额外的参数 _。这个参数名 _ 是一个常见的约定,用于表示这个参数在方法体内不会被使用。当然,你可以选择其他名称,但 _ 是一个通用的占位符,表明这个参数是“不需要的”。

现在,当 next_button 被点击时,next_img 方法会被调用,并且 Qt 会自动传递一个参数(通常是 next_button 的引用)给这个方法。由于我们已经在方法定义中包含了这个额外的参数,所以不会再出现 TypeError。

如果你确实需要在方法体内使用这个发送者对象(比如检查是哪个按钮被点击了),你可以给这个参数一个更有意义的名称,并在方法体内使用它。但在这个例子中,看起来我们并不需要这个发送者对象,所以使用 _ 作为参数名是一个合适的解决方案。

Next:
python中使用自定义线程