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

时间:2016-12-17 19:59:30

标签: python file pickle configparser shelve

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

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

在Linux上运行相同的代码(使用Python 2.7的Ubuntu 16.04.1 LTS)时,一切都按预期运行pickleshelve版本。设置已正确保存并从文件中加载。难道我做错了什么?它是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()

1 个答案:

答案 0 :(得分:0)

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