首页 > 解决方案 > 无法使用pickle Python写入二进制文件

问题描述

所以我遇到了这个问题,我试图将字典写入二进制文件并且没有任何反应。很奇怪; 没有错误信息,什么都没有。就像程序跳过了代码,特别是这段代码

with open("database.dat", "wb") as handle:
        pickle.dump(d, handle)
        handle.close()

如果它存在,我从这个 database.dat 文件加载没有问题,但是如果它不存在,这个代码似乎不会创建一个新的二进制文件,如果它确实存在,它也不会覆盖该文件。我从来没有遇到过这个问题,所以我很困惑......

为了了解这适合的位置,这个函数:

import pickle

def initialise_database(directory, file_name):

    try:
        with open("database.dat", "rb") as handle:
            d = pickle.load(handle) # THIS WORKS PERFECTLY
            handle.close()
            return d

    except FileNotFoundError:
        return update_database(directory, file_name)


def update_database(directory, file_name):
    import xlrd, os

    # Change directory
    os.chdir(directory)

    try:
        wb = xlrd.open_workbook(file_name)

        sheet = wb.sheet_by_name("FUNDS")

        rows, cols = sheet.nrows, sheet.ncols

        d = {}
        for i in range(rows - 1):
            if sheet.cell_value(i + 1, 0) != "":
                charity = cap(sheet.cell_value(i + 1, 0))

                area_of_work = []
                org = []
                funding = 0

                for x in range(cols):
                    if sheet.cell_value(0, x) == "Area of work":
                        if sheet.cell_value(i + 1, x) != "":
                            area_of_work.append(cap(sheet.cell_value(i + 1, x)))
                        else:
                            pass

                    elif sheet.cell_value(0, x) == "Organisation funded":
                        if sheet.cell_value(i + 1, x) != "":
                            org.append(cap(sheet.cell_value(i + 1, x)))
                        else:
                            pass


                    elif sheet.cell_value(0, x) == "How much funding provided":
                        funding = (str_to_int(sheet.cell_value(i + 1, x)))

                        if funding is False:
                            print("\nCharity " + str(sheet.cell_value(i + 1, 0)) + ", number " + str(i + 2) + " has funding of value: "+ str(funding) + ", which is not compatible. Please find it and fix it in the the excel file. Then try again")
                            return False

                # Adds entry to dictionary
                d[charity] = [area_of_work, org, funding]

            else:
                pass

        # After the loop has finished, it should write the entire dictionary to a newly created file!

        with open("database.dat", "wb") as handle:
            pickle.dump(d, handle)
            handle.close()

        return d

    except FileNotFoundError:
        print("File could not be found.")
        print("Program terminating.\n\nPress the enter key to exit.")

我已经查看了其他问题,但似乎没有人涉及我在这里面临的问题。任何有关如何修复它的帮助将不胜感激!

编辑:我还想在运行代码并执行时添加它

print(initialise_database( #my_directory, #my_file )

它确实打印出我的数据库,这意味着正在调用 update() 函数,因为任何地方都没有这样的 database.dat 文件

作为文件没有出现的证据,这里是一个截图。这是在运行 full_script(此代码的来源)之后。

没有文件的证据

标签: pythoniopicklebinaryfiles

解决方案


我会改变:

# Change directory
os.chdir(directory)
wb = xlrd.open_workbook(file_name)

成为:

import os.path

wb = xlrd.open_workbook(os.path.join(directory, file_name))

这样“工作目录”就不会改变,你的文件最终会在你期望的地方。

稍微解释一下:每当您open()创建一个文件时(这是 Python 最终调用的,就像xlrd任何其他本机代码一样)。不以 a /(或\在 Windows 中)开头的路径与您的“当前工作目录”(CWD)或只是工作目录/文件夹相关。您的 CWD 将从启动您的代码的程序(例如您的 shell 或 IDE)继承,但您可以像使用os.chdir.

我通常远离更改目录,因为它往往会引起混乱(正如您所经历的那样)并且只使用到达正确位置的路径。互联网上有很多关于此的更好的文档。Microsoft 有一个名为Naming Files, Paths, and Namespaces的文档,其中包含所有血腥的细节,并且在 Unix/Linux 中通常更容易。尝试搜索“相对与绝对”路径名,并找出..含义。


推荐阅读