Python 2.7 中未正确写入文件的更改

Changes not written to file correctly in Python 2.7

几天来,我一直在努力解决一个问题,即当程序重新启动时,我的设置 class 为解析器编写的设置不会持久存在。此问题仅在 Windows 上出现,但在 Python x86 和 x64 环境中以及使用 PyInstaller 编译时都会出现。程序是否 运行 作为管理员也无关紧要。 当程序第运行s时,write_def(self)被构造函数调用。此函数编写器默认正确指定文件。在此之后,read_set(self) 被调用,所以 class 变量是 set.These class 变量然后匹配默认值。 在另一个文件中,namely frames.pywrite_set(self) 被调用,所有设置都作为参数传递。使用 print 语句我断言 write_set(self) 函数接收到正确的值。将设置写入文件时没有发生错误,当再次 运行ning read_set(self) 时,新设置被正确读取,这也显示在 GUI 中。 但是,当关闭程序并再次 运行ning 时,会再次显示默认设置。这不是我预期的行为。

下面我添加了设置 class 实现 cPickle。使用 pickle 时,行为是相同的。在 this file 中使用 shelve 时,行为是相同的。使用 dill 时,行为是相同的。当实现 ConfigParser.RawConfigParser(在之前链接的 GitHub 存储库的 configparser 分支中)时,行为是相同的,此外,当在文本编辑器中查看设置文件时,可以看到文件未更新。

当 运行 在 Linux 上使用相同的代码(Ubuntu 16.04.1 LTS 与 Python 2.7)时,pickle 一切正常和 shelve 个版本。设置已正确保存并从文件加载。难道我做错了什么? Python 是 Windows 的特定问题吗?

提前感谢您的帮助!

RedFantom.

# Written by RedFantom, Wing Commander of Thranta Squadron and Daethyra, Squadron Leader of Thranta Squadron
# Thranta Squadron GSF CombatLog Parser, Copyright (C) 2016 by RedFantom and Daethyra
# For license see LICENSE

# UI imports
import tkMessageBox
# General imports
import getpass
import os
import cPickle
# Own modules
import vars

# Class with default settings for in the settings file
class defaults:
    # Version to display in settings tab
    version = "2.0.0_alpha"
    # Path to get the CombatLogs from
    cl_path = 'C:/Users/' + getpass.getuser() + "/Documents/Star Wars - The Old Republic/CombatLogs"
    # Automatically send and retrieve names and hashes of ID numbers from the remote server
    auto_ident = str(False)
    # Address and port of the remote server
    server = ("thrantasquadron.tk", 83)
    # Automatically upload CombatLogs as they are parsed to the remote server
    auto_upl = str(False)
    # Enable the overlay
    overlay = str(True)
    # Set the overlay opacity, or transparency
    opacity = str(1.0)
    # Set the overlay size
    size = "big"
    # Set the corner the overlay will be displayed in
    pos = "TL"
    # Set the defaults style
    style = "plastik"

# Class that loads, stores and saves settings
class settings:
    # Set the file_name for use by other functions
    def __init__(self, file_name = "settings.ini"):
        self.file_name = file_name
        # Set the install path in the vars module
        vars.install_path = os.getcwd()
        # Check for the existence of the specified settings_file
        if self.file_name not in os.listdir(vars.install_path):
            print "[DEBUG] Settings file could not be found. Creating a new file with default settings"
            self.write_def()
            self.read_set()
        else:
            try:
                self.read_set()
            except:
                tkMessageBox.showerror("Error", "Settings file available, but it could not be read. Writing defaults.")
                self.write_def()
        vars.path = self.cl_path

    # Read the settings from a file containing a pickle and store them as class variables
    def read_set(self):
        with open(self.file_name, "r") as settings_file_object:
            settings_dict = cPickle.load(settings_file_object)
        self.version = settings_dict["version"]
        self.cl_path = settings_dict["cl_path"]
        self.auto_ident = settings_dict["auto_ident"]
        self.server = settings_dict["server"]
        self.auto_upl = settings_dict["auto_upl"]
        self.overlay = settings_dict["overlay"]
        self.opacity = settings_dict["opacity"]
        self.size = settings_dict["size"]
        self.pos = settings_dict["pos"]
        self.style = settings_dict["style"]

    # Write the defaults settings found in the class defaults to a pickle in a file
    def write_def(self):
        settings_dict = {"version":defaults.version,
                         "cl_path":defaults.cl_path,
                         "auto_ident":bool(defaults.auto_ident),
                         "server":defaults.server,
                         "auto_upl":bool(defaults.auto_upl),
                         "overlay":bool(defaults.overlay),
                         "opacity":float(defaults.opacity),
                         "size":defaults.size,
                         "pos":defaults.pos,
                         "style":defaults.style
                        }
        with open(self.file_name, "w") as settings_file:
            cPickle.dump(settings_dict, settings_file)

    # Write the settings passed as arguments to a pickle in a file
    # Setting defaults to default if not specified, so all settings are always written
    def write_set(self, version=defaults.version, cl_path=defaults.cl_path,
                  auto_ident=defaults.auto_ident, server=defaults.server,
                  auto_upl=defaults.auto_upl, overlay=defaults.overlay,
                  opacity=defaults.opacity, size=defaults.size, pos=defaults.pos,
                  style=defaults.style):
        settings_dict = {"version":version,
                         "cl_path":cl_path,
                         "auto_ident":bool(auto_ident),
                         "server":server,
                         "auto_upl":bool(auto_upl),
                         "overlay":bool(overlay),
                         "opacity":float(opacity),
                         "size":str(size),
                         "pos":pos,
                         "style":style
                        }
        with open(self.file_name, "w") as settings_file_object:
            cPickle.dump(settings_dict, settings_file_object)
        self.read_set()

有时需要一段时间才能得到答案,我只是想到了这个:Windows 上发生但 Linux 上没有发生的事情?该问题的答案是:将目录更改为正在解析的文件的目录。然后很明显:设置已正确存储,但在程序中创建设置文件的文件夹发生了变化,因此设置不会写入原始设置文件,而是在另一个文件夹中创建了一个新的设置文件位置。