【Debug】Python第三方包Error记录

1、int() argument must be a string, a bytes-like object or a number, not ‘KeyboardModifier‘

说明

根据Python官网,Python3.7还支持WIN7。
项目对应的requirements.txt为:

cycler==0.11.0
fonttools==4.38.0
kiwisolver==1.4.4
matplotlib==3.5.3
Nuitka==1.5.7
numpy==1.21.6
ordered-set==4.1.0
packaging==23.1
Pillow==9.5.0
pyparsing==3.0.9
PySide2==5.15.2.1
python-dateutil==2.8.2
shiboken2==5.15.2.1
six==1.16.0
typing-extensions==4.5.0
zstandard==0.21.0

项目对应的nuitka命令为:

nuitka --standalone  --output-dir=out  --plugin-enable=pyside2  --nofollow-import-to=tkinter  --windows-disable-console

解决方案

from matplotlib.backends.backend_qt5agg import FigureCanvasQTAgg as FigureCanvas
from matplotlib.backends.backend_qt5agg import NavigationToolbar2QT as NavigationToolbar

报错主要是PySide6与matplotlib之间接口兼容性的问题。报错位置代码

_MODIFIER_KEYS = [
    (_to_int(getattr(_enum("QtCore.Qt.KeyboardModifier"), mod)),
     _to_int(getattr(_enum("QtCore.Qt.Key"), key)))
    for mod, key in [
        ("ControlModifier", "Key_Control"),
        ("AltModifier", "Key_Alt"),
        ("ShiftModifier", "Key_Shift"),
        ("MetaModifier", "Key_Meta"),
    ]
]

根据gpt,

这段代码是一个用于将 Qt 的键盘修饰符和按键转换为整数类型的列表。具体来说,代码中定义了一个名为 _MODIFIER_KEYS 的列表,其中包含了 4 个二元组,每个二元组分别表示一个修饰符和对应的按键,且每个元素都是整数类型。
这段代码通过调用 getattr() 方法获取了 PySide6.QtCore.Qt.KeyboardModifier 和 PySide6.QtCore.Qt.Key 枚举类对应的属性,使用 _to_int() 函数将枚举值转换为整数类型,并最终构造成二元组的形式存放在 _MODIFIER_KEYS 列表中。
这个列表可以用于接收 Qt 的快捷键事件后进行处理,比如判断按下的键是否为某个快捷键等。
需要注意的是,这里使用了 _enum() 函数获取枚举类,但代码中未给出该函数的实现,可能是在其他地方定义的函数,因此如果要运行这段代码,还需要先确保 _enum() 函数已经定义并导入。

根据matplotlib官方issues,解决方案是,

mpl 升级到 >=3.6.2 或将 pyside 降级到 <6.4.0

Python3.7下matplotlib,最高支持3.5,因而使用pyside==6.3.0,此时需要注意NavigationToolbar2QT需要canvas,parent两个参数。

class NavigationToolbar2QT(NavigationToolbar2, QtWidgets.QToolBar):
.......
    def __init__(self, canvas, parent, coordinates=True):
.......

2、Pandas Excel file format cannot be determined, you must specify an engine manually.

说明

Pandas读取Excel报错
Excel file format cannot be determined, you must specify an engine manually.
在这里插入图片描述
pd.read_excel方法本身是支持多种引擎的,包括"xlrd", “openpyxl”, “odf”, “pyxlsb”,更换引擎后依然失效!

Debug

我们直接用可以直接用open with打开源文件

    with open(ipath, 'r', encoding='utf-8') as f:
        print(f.read())

神奇的一幕发生了,
在这里插入图片描述
有的文件名义上是Excel,其实内心是个Html!

解决办法

使用pd.read_html方法

df = pd.read_html(ipath, header=2)[0]

3、pymupdf\utils.py", line 3625, in insert_text maxcode = max([ord© for c in " ".join(text)]) ValueError: max() arg is an empty sequence

pymupdf生成pdf时,大部分文件正常,遇到个别文件报错,
这个报错在vscode中会进一步提示:
ValueError: path is on mount 'C:', start on mount 'E:'

Debug

刚开始一直以为是文件路径的问题,豆包提示的是

这是一段复杂的错误追踪信息,表明在使用 `pymupdf` 进行相关操作时出现了问题。

错误主要集中在 `utils.py` 这个文件中的 `insert_text` 函数。

首先,`ValueError: max() arg is an empty sequence` 这个错误意味着在计算 `max([ord(c) for c in " ".join(text)])` 时,`text` 可能为空,导致无法找到最大值。

然后,在处理这个异常时,又引发了一系列后续的异常。包括在 `main_test.py` 中的某些操作,如 `PdfPhaser().generate_report(pdf_path)` 调用中,以及在后续的 `insert_text` 操作中出现问题。

最后,还出现了与文件路径相关的错误 `ValueError: path is on mount 'C:', start on mount 'E:'` ,这可能表示您正在尝试在不同的磁盘挂载点之间进行不恰当的文件路径操作。

例如,如果您的代码原本期望在 `E:` 盘读取或写入文件,但实际提供的路径在 `C:` 盘,就可能导致这种错误。或者在处理文件路径时,没有正确处理不同磁盘挂载点之间的差异。

要解决这个问题,您需要仔细检查以下几个方面:
1. 确认 `text` 的值是否正确被传递和初始化,确保它不为空。
2. 检查 `pdf_path` 以及相关的文件路径设置,确保它们与您实际的文件存储位置和操作需求相匹配。
3. 检查代码中涉及到文件路径处理的部分,是否存在逻辑错误或不兼容不同磁盘挂载点的情况。

您能提供更多关于您的代码逻辑和操作目的的信息吗?这将有助于更准确地定位和解决问题。 

这是我一开始的代码

 pbreak = "^p"
 logger.info(f"{text}")
 text = self.add_linebreak(text, font, fontsize, pbreak, pbreak_line=55)
 doc = fitz.open()
 for _text in text.split(pbreak):
     page = doc.new_page()
     page.insert_font(fontname="F0", fontbuffer=font.buffer)
     page.insert_text(
         (50, 50), _text, fontname="F0", fontsize=fontsize
     )  

这是我修改后的代码

 pbreak = "^p"
 logger.info(f"{text}")
 text = self.add_linebreak(text, font, fontsize, pbreak, pbreak_line=55).strip().rstrip(pbreak)
 doc = fitz.open()
 for _text in text.split(pbreak):
     page = doc.new_page()
     page.insert_font(fontname="F0", fontbuffer=font.buffer)
     page.insert_text(
         (50, 50), _text, fontname="F0", fontsize=fontsize
     )  

4、pyinstaller打包Windows的exe文件后,多进程导致程序反复重启

说明

使用pyinstaller打包python成为exe文件时候,因为在程序中使用了multiprocessing的Process在程序中创建多进程,导致打包后的exe文件,只要运行到Process创建进程的地方,就重启整个exe文件。

解决方法

例如有两个文件
plot.py

import pyqtgraph as pg
from pyqtgraph.widgets.RemoteGraphicsView import RemoteGraphicsView

def plot():
    app = pg.mkQApp()

    ## Create the widget
    v = RemoteGraphicsView(debug=False)  # setting debug=True causes both processes to print information
                                        # about interprocess communication
    v.show()
    v.setWindowTitle('pyqtgraph example: RemoteGraphicsView')


    plt = v.pg.PlotItem()

    v.setCentralItem(plt)
    plt.plot([1,4,2,3,6,2,3,4,2,3], pen='g')
    pg.exec()

在main.py需要开启freeze_support

import multiprocessing
if __name__ == '__main__':
    multiprocessing.freeze_support()
    from plot import plot
    plot()
  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

KmBase

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值