Seit ein paar Tagen habe ich mit einem Problem zu kämpfen, nämlich dass die Einstellungen, die von meiner Einstellungsklasse für einen Parser geschrieben wurden, nicht persistent sind, wenn das Programm neu gestartet wird. Dieses Problem tritt nur unter Windows auf, aber sowohl in Python x86- als auch in x64-Umgebungen und bei der Kompilierung mit PyInstaller. Es spielt auch keine Rolle, ob das Programm als Administrator ausgeführt wird oder nicht. Wenn das Programm zum ersten Mal ausgeführt wird, wird write_def(self)
vom Konstruktor aufgerufen. Diese Funktion Writers korrekt auf die angegebene Datei voreingestellt. Danach wird read_set(self)
aufgerufen, so dass die Klassenvariablen gesetzt werden. Diese Klassenvariablen stimmen dann mit den Standardwerten überein. In einer anderen Datei wird namely frames.py, write_set(self)
aufgerufen, und alle Einstellungen werden als Argumente übergeben. Mit print-Anweisungen habe ich festgestellt, dass die write_set(self)
Funktion die richtigen Werte erhält. Beim Schreiben der Einstellungen in die Datei treten keine Fehler auf, und wenn Sie read_set(self)
erneut ausführen, werden die neuen Einstellungen korrekt gelesen, und dies wird auch in der GUI angezeigt. Wenn Sie das Programm jedoch schließen und erneut ausführen, werden die Standardeinstellungen erneut angezeigt. Das ist nicht das Verhalten, das ich erwartet habe.Änderungen nicht korrekt in Python geschrieben 2.7
Unten habe ich die Einstellungen Klasse eine cPickle
Implementierung hinzugefügt. Bei Verwendung von pickle
ist das Verhalten identisch. Wenn Sie shelve
wie in verwenden, ist das Verhalten das gleiche. Bei Verwendung von dill
ist das Verhalten identisch. Bei der Implementierung eines ConfigParser.RawConfigParser
(im configparser-Zweig des GitHub-Repositorys, mit dem zuvor verlinkt wurde) ist das Verhalten gleich, und zusätzlich wird beim Anzeigen der Einstellungsdatei in einem Texteditor angezeigt, dass die Einstellungen in der Datei nicht aktualisiert werden.
Wenn Sie den gleichen Code unter Linux (Ubuntu 16.04.1 LTS mit Python 2.7) ausführen, funktioniert alles wie erwartet mit pickle
und shelve
Versionen. Die Einstellungen werden korrekt gespeichert und von der Datei geladen. Mache ich etwas falsch? Ist es ein Windows-spezifisches Problem mit Python?
Vielen Dank im Voraus für jede Hilfe!
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()