【发布时间】:2020-12-05 17:16:57
【问题描述】:
我遇到了一个奇怪的问题,Python 会成功找到并读取存在的二进制文件,但 pickle.load() 不会。 pickle.load() 正在抛出一个没有多大意义的 FileNotFoundError。我知道该文件确实存在,因为如果我尝试读取文件的内容,我就可以。
try:
with open("test", "rb") as f:
print(f.read())
data = pickle.load(f)
except FileNotFoundError as e:
print(e)
几个小时以来,我一直在努力解决这个问题,但我就是不明白这里发生了什么。我有相当多的 Python 份额,但从未发生过这种情况。使用 VSCode 和 WSL (Ubuntu 20.04) 在 Windows 10 上工作。
编辑:我知道这个特定的代码不起作用,因为我首先使用 f.read() 阅读。我只是把它放在那里表明它有效,我只想pickle.load()它。
编辑:回溯是这样的:
Traceback (most recent call last):
File "/mnt/d/_/Projects/FCUL/SO/pgrepwc/v2/hpgrepwc.py", line 34, in main
data = pickle.load(f)
File "/usr/lib/python3.8/multiprocessing/managers.py", line 959, in RebuildProxy
return func(token, serializer, incref=incref, **kwds)
File "/usr/lib/python3.8/multiprocessing/managers.py", line 809, in __init__
self._incref()
File "/usr/lib/python3.8/multiprocessing/managers.py", line 863, in _incref
conn = self._Client(self._token.address, authkey=self._authkey)
File "/usr/lib/python3.8/multiprocessing/connection.py", line 502, in Client
c = SocketClient(address)
File "/usr/lib/python3.8/multiprocessing/connection.py", line 630, in SocketClient
s.connect(address)
FileNotFoundError: [Errno 2] No such file or directory
根据要求,我的目录列表:
prgrepwc:
|
| histFile1
| histFile2
| .gitattributes
| .gitignore
| testFile
|
+---.vscode
| launch.json
| settings.json
|
|
\---v2
|
| testFile
| histFile
| hpgrepwc.py
| Load.py
| Match.py
| pgrepwc_v2.py
\-- README.txt
我正在执行的文件是文件夹v2 中的hpgrepwc.py。我要读取的文件是二进制文件testFile。我注意到即使我的脚本在文件夹v2 中,有时它默认为pgrepwc,所以我什至在其中放置了testFile 的副本以防万一。无论如何都没有骰子,我也尝试将文件保存为.bin,但无济于事。
解决方案:
@tdelaney 提到:
"(...) 它看起来像是在 multiprocessing.Manager 中创建的某个对象 被腌制了。但这些对象实际上是广播的代理 对一组子流程的更改,并且在此之外无效 语境。在您的情况下, unpickler 试图重建一个类 试图重新连接到其早已死去的多处理合作伙伴。 您需要查看进行酸洗的代码并找出一些 其他封装数据的方式。”
就是这样。我在代码中大量使用multiprocessing.Manager 作为共享内存数据结构。在将 manager.dict() 转换为普通的 Python dict 之后,酸洗和解酸就像一个魅力。再次感谢所有做出贡献的人,尤其是@tdelaney。
【问题讨论】:
-
此代码不起作用,因为您在尝试取消腌制之前已阅读到文件末尾。这应该导致 EOFError,而不是 FileNotFoundError。如果错误出现在
open调用上,那么问题只是当前工作目录中没有名为“test”的文件。我要求回溯,以便我们可以看到完整的错误消息和失败的行。 -
@NavaneethReddy - 这是不正确的。文件不需要扩展名。 Microsoft Windows 允许您通过文件扩展名将程序与文件相关联,并且不会执行代码,除非它具有
.exe或其他明确定义的扩展名。类 Unix 系统不是这样工作的,并且通常不关心扩展名(如果有的话)是什么。在这种情况下,OP 打开文件并将文件句柄传递给pickle。 Pickle 只是读取那个文件,根本不在乎它来自哪里。 -
@zeval - 但读取有效吗?您可以将
import traceback;traceback.print_exc()添加到您的异常处理程序中以打印回溯,以便我们可以看到程序失败的位置。 -
@Zeval 您在代码中使用多处理/进程吗?这可能是相关的:stackoverflow.com/questions/56641428/…。该错误似乎与此问题中描述的错误有些相关
-
通过该编辑,看起来在
multiprocessing.Manager中创建的某些对象被腌制了。但这些对象实际上是向一组子进程广播更改的代理,并且在该上下文之外无效。在您的情况下,unpickler 试图重建一个试图重新连接到其长期死亡的多处理伙伴的类。您需要查看进行酸洗的代码并找出封装数据的其他方法。