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.py、write_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 上没有发生的事情?该问题的答案是:将目录更改为正在解析的文件的目录。然后很明显:设置已正确存储,但在程序中创建设置文件的文件夹发生了变化,因此设置不会写入原始设置文件,而是在另一个文件夹中创建了一个新的设置文件位置。
几天来,我一直在努力解决一个问题,即当程序重新启动时,我的设置 class 为解析器编写的设置不会持久存在。此问题仅在 Windows 上出现,但在 Python x86 和 x64 环境中以及使用 PyInstaller 编译时都会出现。程序是否 运行 作为管理员也无关紧要。
当程序第运行s时,write_def(self)
被构造函数调用。此函数编写器默认正确指定文件。在此之后,read_set(self)
被调用,所以 class 变量是 set.These class 变量然后匹配默认值。
在另一个文件中,namely frames.py、write_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 上没有发生的事情?该问题的答案是:将目录更改为正在解析的文件的目录。然后很明显:设置已正确存储,但在程序中创建设置文件的文件夹发生了变化,因此设置不会写入原始设置文件,而是在另一个文件夹中创建了一个新的设置文件位置。