Python、tkinter 和导入的类:记录未捕获的异常

2023-12-20

我正在编写一些想要与我的团队共享的脚本,因此我一直在构建一堆日志记录,以便在他们在某个地方遇到崩溃时更容易进行调试,从那时起我就可以看到到底发生了什么崩溃。

一般记录到文件没有问题,但我有一个未捕获的异常问题。我尝试了各种方法来让它工作,例如this https://stackoverflow.com/questions/6234405/logging-uncaught-exceptions-in-python and this https://stackoverflow.com/questions/20714644/python-sys-excepthook-and-logging-uncaught-exceptions-across-multiple-modules。当我从 IDLE 或命令提示符运行它时,似乎 sys.excepthook 没有被调用。

昨天,如果异常发生在主模块中,它会正确记录,但如果异常发生在导入的类中,则不会正确记录。现在异常根本不会被记录,我不知道我改变了什么(所以我今天安装了 Git :-P)

这是我试图开始工作的代码,即主模块:

import tkinter as tk
import sys
import traceback
import logging
import datetime

import exception_logging_test_imported_class as impclass

# Main Class
class ExceptMain(tk.Frame):
    def __init__(self, parent):
        logging.info('Start main')
        tk.Frame.__init__(self, parent, relief='groove', bd=4)
        self.parent = parent
        self.pack()
        tk.Label(self, text='This is the main class', bg='white').pack()
        tk.Button(self, text='Start subframe', command=self.run).pack()
        tk.Button(self, text='Throw main exception', command=self.throwex).pack()
        tk.Button(self, text='Start imported class', command=self.start_import).pack()

    # Function to start another frame, from this same file
    def run(self):
        logging.info('Run main function')
        subclass = ExceptSubclass(self)
        subclass.pack()

    # Function to start an imported frame class
    def start_import(self):
        imported_class = impclass.ExtraClass(self)
        imported_class.pack()

    # Throw an exception
    def throwex(self):
        raise ValueError("Main is burning down")

#Another class in this file
class ExceptSubclass(tk.Frame):
    def __init__(self, parent):
        logging.info('Start subframe')
        tk.Frame.__init__(self, parent, relief='groove', bd=4)
        self.parent = parent
        self.pack()
        tk.Label(self, text='This is the subclass', bg='white').pack()
        tk.Button(self, text='run sub function', command=self.script).pack()
        tk.Button(self, text='Throw sub exception', command=self.throwexsub).pack()

    # Run something
    def script(self):
        logging.info('Run subfunction')
        tk.Label(self, text='Script has run').pack()

    # Throw an exception
    def throwexsub(self):
        thing = []
        thing[1]

# Use a logger object or just logging
logger_not_just_logging = False
if logger_not_just_logging:
    logger = logging.getLogger()
    logger.setLevel(logging.DEBUG)
    logger.addHandler(logging.FileHandler("ZZ_logging_test.log"))
else:
    logging.basicConfig(filename='ZZ_logging_test.log', level=logging.DEBUG)

logging.info('<<<<< STARTING NEW INSTANCE >>>>>')

# This function needs to be called somehow when an uncaught exception happens
def exception_handler(etype, value, tb):
    logging.exception("Uncaught exception: {0}".format(str(value)))
    with open('ZZ_exception_test.log', 'a') as file:
        file.write("<<< Exception occurred at " + str(datetime.datetime.now()) + " >>>")
        traceback.print_exception(etype, value, tb, file=file)

# Install the hook  
sys.excepthook = exception_handler

# Run the app
root = tk.Tk()
app = ExceptMain(root)
root.mainloop()

还有一个子模块:

import tkinter as tk
import logging

# This is an imported frame
class ExtraClass(tk.Frame):
    def __init__(self, parent):
        logging.info('Start imported frame')
        tk.Frame.__init__(self, parent, relief='groove', bd=4)
        self.parent = parent
        self.pack()
        tk.Label(self, text='This is an imported frame', bg='white').pack()
        tk.Button(self, text='run imported frame function', command=self.script).pack()
        tk.Button(self, text='Throw imported exception', command=self.throwexsub).pack()

    # Imported frame has a function
    def script(self):
        logging.info('Run imported frame function')
        tk.Label(self, text='Imported script has run').pack()

    # Imported frame throws an exception
    def throwexsub(self):
        thing = []
        thing[1]

我期望得到的是一个包含所有常规日志记录的文件和一个包含异常和堆栈跟踪的单独文件。

如果您能帮我解决这个问题,我将永远感激不已!


啊哈,我发现问题了。 以上述方式安装的 excepthook 仅在较高级别上工作。当我注意到我的类抛出的异常仍在控制台中记录而键盘中断确实按我想要的方式记录在文件中时,我发现了这一点。

接下来我发现在 Python 中使用线程时可能会遇到类似的问题。主线程仍将按需要记录,但其他线程中的异常不会记录。然后我发现类可以覆盖我对异常处理方式的覆盖。由于我的所有代码都在 tkinter 主循环中运行,我可能需要告诉该位执行我想要它执行的操作。这种洞察使我this https://stackoverflow.com/questions/32189391/handle-uncaught-exceptions-with-tkinter所以答案和一行代码一切都被修复了,一直在主类的末尾:

# Run the app
root = tk.Tk()
root.report_callback_exception = exception_handler # this here.
app = ExceptMain(root)
root.mainloop()
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Python、tkinter 和导入的类:记录未捕获的异常 的相关文章

随机推荐

  • 为什么 PHP 中 65.6*100%10 等于 9 而不是 0?

    echo 65 7 100 10 0 echo 65 6 100 10 9 lt echo 6560 10 0 echo 65 5 100 10 0 有人可以解释一下为什么吗 EDIT 对于人类或非程序员来说 结果 9 显然是错误的 我怎样
  • 在 Outlook html 电子邮件中,浮动不起作用

    我想要这样的布局 其中有一个矩形框 左边的盒子里有一个文本 右边有一个图像 这在浏览器中看起来很好 但是当作为 html 电子邮件发送时 在 Outlook 中浮动权限似乎不起作用 它将图像放在文本下方的下一行 关于如何实现这项工作有什么想
  • html 表格如何通过更改悬停时的边框来突出显示列?

    我正在探索如何设计表格样式 以便当鼠标悬停在列上时可以更改边框 当鼠标悬停在一列上时 我想通过更改边框颜色来突出显示该列 需要强调的是 我将以下 JavaScript 代码与 jQuery 库结合使用 td hover function v
  • 构造函数:默认参数和委托参数之间的区别

    今天 我偶然发现这些标准声明 http en cppreference com w cpp container vector vector of std vector构造函数 until C 14 explicit vector const
  • 如何使用 pip 将 vcs 中的 Python 包可编辑安装到特定目录中?

    默认情况下 pip 安装editable打包成srcPython安装目录的子目录 我想使用 pip 支持从源代码控制中检出软件包 将版本控制中的软件包安装到我选择的目录中 例如 pip install e git https github
  • HATEOAS 中“_embedded”的含义和用法

    我正在使用 Spring Data REST 它支持 HATEOAS 我对这个范式很陌生 In GET来自我的 RESTful Web 服务的响应 我经常在名为的节点内收到结果 embedded 我在想 what is embedded节点
  • JPanel 在 JFrame 上没有改变

    我的想法是拥有一个 全局 JFrame 然后我可以根据需要添加 删除 JPanel 以创建一个流畅的应用程序 目前 当我尝试从第一个 JPanel 更改为第二个 JPanel 时 第二个 JPanel 将不会显示 我的代码如下 处理程序 运
  • 计算每个段落中的字符数

    我正在尝试找到一种方法来计算页面上每个段落中的字符数 我发现下面这个小片段可以计算每个段落中的单词数 效果很好 是否可以修改为也包括字符数 互联网上有很多解决方案 但它们只关注特定的字符串或文本区域 并且往往变得非常长和复杂 我不介意计数中
  • 使用默认值从 Mac 上的命令行修改 Plist

    有谁知道如何使用命令行修改 Plist 文件defaults 目前有两个词典URL types大批 我需要添加另一个 我尝试过的每个命令要么替换了整个字典 要么创建了一个名为的新数组URL types而不是编辑它 关于如何在默认情况下完成此
  • 如何检测数据集中的所有空列并删除\删除它们?

    正如标题中所建议的 我想删除所有空列 变量 其中所有记录均为空或等于 null 或 以减少以后执行的时间成本 详细场景 我有一个包含 1000 列的 dataset 其中一些 很多是空的 现在我想创建一个新的数据集 其中需要在先前数据集的某
  • 如何存储由 std::unique_ptr 给出的抽象类的对象向量?

    我有一个循环 其中我使用一个函数将 std unique ptr 返回到抽象类的对象 我想通过push back将这些对象存储到std vector中 但由于对象是抽象类型 我收到以下错误 error cannot allocate an
  • 防止 Perl 中的循环引用内存泄漏

    我最近问了一个question https stackoverflow com questions 31971633 perl memory management when overwriting objects关于 Perl 中的覆盖对象
  • 如何在asp.net core中将ViewDataDictionary与Html.Partial一起使用?

    我的案例是这样的 Model public class Book public string Id get set public string Name get set public class Comment public string
  • 如何通过spark REST API获取所有作业状态?

    我正在使用 Spark 1 5 1 我想通过 REST API 检索所有作业状态 我使用得到正确的结果 api v1 applications appId 但在找工作的同时 api v1 applications appId jobs得到
  • 金字塔和变色龙中的ajax小部件

    我希望能够在服务器端轻松创建由变色龙和金字塔支持的ajax 小部件 Pyramid 是否提供任何可以使编写小部件变得容易的管道代码 我当前的方法是我有一个使用 home pt 作为渲染器的主视图 home pt 使用宏 base pt 定义
  • 如何在 CUDA 中进行原子加载

    我的问题是如何在 CUDA 中进行原子加载 原子交换可以模拟原子存储 原子加载是否可以以类似的方式廉价地模拟 我可以使用带有 0 的原子添加来自动加载内容 但我认为它很昂贵 因为它执行原子读取 修改 写入而不是仅读取 除了使用volatil
  • android-support-v7-mediarouter 中的 styles.xml 错误

    以下是 android support v7 mediarouter 的 styles xml 文件
  • 如何在多个文件中导入常量

    我有一个包含许多模块的包 每个模块都使用我在每个文件中独立定义的常量 然而 所有这些常数必须彼此一致 所以我尝试在单个文件中定义它们并将其导入每个文件中 当我运行它时 出现未找到常量的错误 他们是让许多其他人导入单个文件并包含常量的干净方法
  • 在 JavaScript 中将 DOM 节点或文档转换为 XML

    假设您在 JavaScript 中收到一个 DOM 元素或文档 例如 window document 您如何将其转换为有效的 XML 更具体地说 对于我的示例 我有一个显示 SVG 的网页 该 SVG 有大量 JavaScript 来允许交
  • Python、tkinter 和导入的类:记录未捕获的异常

    我正在编写一些想要与我的团队共享的脚本 因此我一直在构建一堆日志记录 以便在他们在某个地方遇到崩溃时更容易进行调试 从那时起我就可以看到到底发生了什么崩溃 一般记录到文件没有问题 但我有一个未捕获的异常问题 我尝试了各种方法来让它工作 例如