INI-Datei überprüfen

Wenn du dir nicht sicher bist, in welchem der anderen Foren du die Frage stellen sollst, dann bist du hier im Forum für allgemeine Fragen sicher richtig.
Benutzeravatar
Sophus
User
Beiträge: 1109
Registriert: Freitag 25. April 2014, 12:46
Wohnort: Osnabrück

Hallo Leute, ich habe ein kleines Problem. Die Fehlermeldung, die ich jedesmal erhalte, seht ihr am Ende des Themas.
Um etwas Übersicht zu bekommen: Ich habe zwei Funktionen geschrieben, einmal generate_constants_sections_options und einmal check_setions_options. In der ersten Funktion habe ich zunächst zwei Wörterbücher erstellt. Ein Wörterbuch, in welches nur Bereiche (Sectione) untergebracht werden, und ein Wörterbuch, in welcher Optionen gesammelt werden. Im nächsten Schritt habe ich zwei Listen erstellt. In section_general_list werden Bereiche und Optionen zueinander kombiniert. Genauso verhält es sich mit section_gui_list . Auf diese Weise weiß ich dann, welche Optionen zu welchen Bereichen gehören. Nun habe ich zwei leere Wörterbücher stellt, die mit Hilfe der zwei darauf folgenden For-Schleifen entsprechend gefüllt werden.

Mein Ziel ist es, dass ich in der check_setions_options()-Funktion die Bereiche, und die dazugehörigen Optionen dazu nutzen möchte, um zu überprüfen, ob die Bereiche überhaupt gibt, und ob es in den Bereichen auch die Optionen gibt. Kurz: Ich möchte meine INI-Datei überprüfen, ob die Bereiche und die dazugehörigen Optionen vorhanden sind. Beim Ausführungen bekomme ich die Fehlermeldung, dass 'list' die Methode 'lower' nciht kennt. Nun frage ich mich, was ich hier falsch mache?

Code: Alles auswählen

#!/usr/bin/env python
# -*- coding:utf-8 -*-

import ConfigParser
import os

config_setting = ConfigParser.SafeConfigParser()

def generate_constants_sections_options():
    dict_sections = {"SECTION_GENERAL": "General_Configuration",
                     "SECTION_GUI": "General_Design",
    }

    dict_options = {"OPTION_LANGUAGE": "language",
                    "OPTION_DATABASE_TYPE": "database_type",
                    "OPTION_ASK_BEFORE_CLOSE": "ask_befor_close",
                    "OPTION_DIR_PATH_TEMP_FOLDER": "dir_path_temp_folder",
                    "OPTION_URL_UPDATE": "url_update",
                    "OPTION_TIME_OUT_UPDATE": "time_out_update",
                    "OPTION_URL_VERSION": "url_version",
                    "OPTION_LAST_FOLDER_PATH_REMEMBER": "last_folder_path_remeber",
                    "OPTION_LOG_FOLDER_PATH": "log_folder_path",
                    "OPTION_GUI_STYLE": "gui_style",
                    "OPTION_SCHEME_COLOR": "scheme_color"
    }

    section_general_list = [
                            [dict_sections["SECTION_GENERAL"], dict_options["OPTION_LANGUAGE"]],
                            [dict_sections["SECTION_GENERAL"], dict_options["OPTION_DATABASE_TYPE"]],
                            [dict_sections["SECTION_GENERAL"], dict_options["OPTION_DIR_PATH_TEMP_FOLDER"]],
                            [dict_sections["SECTION_GENERAL"], dict_options["OPTION_URL_UPDATE"]],
                            [dict_sections["SECTION_GENERAL"], dict_options["OPTION_TIME_OUT_UPDATE"]],
                            [dict_sections["SECTION_GENERAL"], dict_options["OPTION_LAST_FOLDER_PATH_REMEMBER"]]
                            ]

    section_gui_list = [
                        [dict_sections["SECTION_GUI"], dict_options["OPTION_GUI_STYLE"]],
                        [dict_sections["SECTION_GUI"], dict_options["OPTION_SCHEME_COLOR"]]
                        ]

    dict_sections_general = {}

    dict_sections_gui = {}

    for key, val in section_general_list:
        '''
        The magic of setdefault is that it initializes
        the value for that key if that key is not defined,
        otherwise it does nothing. Now, noting that setdefault
        returns the key you can combine these into a single line:
        '''
        dict_sections_general.setdefault(key, []).append(val)

    for key_1, val_1 in section_gui_list:
        dict_sections_gui.setdefault(key_1, []).append(val_1)

    return dict_sections_general, dict_sections_gui


def check_setions_options(ini_path):
    '''
    First, its necessary to get all generated sections and options.
    All generated sections and options are saved in the variables (sec_opt_gen) and (sec_opt_gui ).
    '''
    sec_opt_gen, sec_opt_gui = generate_constants_sections_options()
    print "SECTION_OPTION_GENERAL", sec_opt_gen
    print "SECTION_OPTION_GUI", sec_opt_gui
    '''
    This empty list was created for sections
    that exists and that are correct. All existing
    and correct sections are added to this list.
    '''

    '''
    Open and read the ini-file. The open file are saved in
    the variable (open_ini). In this way you can later access
    the object - for example to close it later.
    '''
    open_ini = config_setting.read(ini_path)

    '''
    Iterate over the dictionary, especially the values: result.values().
    '''
    for candidate_section_gen in sec_opt_gen.keys():
        print '(%s) section exists: %s' % (candidate_section_gen, config_setting.has_section(candidate_section_gen))
        for candidate_option_gen in sec_opt_gen.values():
            print '%s.%-12s  : %s' % (candidate_section_gen, candidate_option_gen, config_setting.has_option(candidate_section_gen, candidate_option_gen))
    for candidate_section_gui in sec_opt_gui.keys():
        print '(%s) section exists: %s' % (candidate_section_gui, config_setting.has_section(candidate_section_gui))
        for candidate_option_gui in sec_opt_gui.values():
            print '%s.%-12s  : %s' % (candidate_section_gui, candidate_option_gui, config_setting.has_option(candidate_section_gui, candidate_option_gui))

    open_ini.close()
if __name__ == "__main__":
    path_to_ini_file = raw_input("Enter Path: ")
    check_setions_options(path_to_ini_file)

So sieht meine derzeitige *.ini-Datei aus. Um zu testen, habe ich den Inhalt meiner Datei als Zitat hinzugefügt.
[General_Configuration]
language =
database_type =
ask_befor_close =
dir_path_temp_folder =
url_update =
time_out_update =
url_version =
last_folder_path_remeber =
log_folder_path =

[General_Design]
gui_style =
scheme_color =
Fehlermeldung:
Traceback (most recent call last):
File "D:/Dan/Python/xarphus/examples/iterate_over_values.py", line 96, in <module>
check_setions_options(path_to_ini_file)
File "D:/Dan/Python/xarphus/examples/iterate_over_values.py", line 87, in check_setions_options
print '%s.%-12s : %s' % (candidate_section_gen, candidate_option_gen, config_setting.has_option(candidate_section_gen, candidate_option_gen))
File "C:\Python27\lib\ConfigParser.py", line 384, in has_option
option = self.optionxform(option)
File "C:\Python27\lib\ConfigParser.py", line 374, in optionxform
return optionstr.lower()
AttributeError: 'list' object has no attribute 'lower'
Benutzeravatar
Sophus
User
Beiträge: 1109
Registriert: Freitag 25. April 2014, 12:46
Wohnort: Osnabrück

Ich konnte das Problem kurz vorm Schlafen gehen "lokalisieren". In der check_setions_options()-Funktion sind meine For-Schleifen nicht tief genug vorgedrungen. Dies habe ich dann wie folgt gelöst: Ich habe die Schleife erweitert:

Code: Alles auswählen

print ""
    for candidate_section_gen in sec_opt_gen.keys():
        print '(%s) section exists: %s' % (candidate_section_gen, config_setting.has_section(candidate_section_gen))
        for candidate_option_gen in sec_opt_gen.values():
            for element in candidate_option_gen:
                print '%s.%-12s  : %s' % (candidate_section_gen, element, config_setting.has_option(candidate_section_gen, element))
    print ""
    for candidate_section_gui in sec_opt_gui.keys():
        print '(%s) section exists: %s' % (candidate_section_gui, config_setting.has_section(candidate_section_gui))
        for candidate_option_gui in sec_opt_gui.values():
            for element_2 in candidate_option_gui:
                print '%s.%-12s  : %s' % (candidate_section_gui, element_2, config_setting.has_option(candidate_section_gui, element_2))
Aber mit einem Blick auf meinen derzeitigen Skript, ist mir aufgefallen, dass er irgendwie "unwartbar" wirkt. Kommt ein neuer Bereich (Section) hinzu, muss dieser in der generate_constants_sections_options()-Funktion in das Wörterbuch dict_sections hinzugefügt werden, und die dazugehörigen Optionen dann in dict_options. Danach müsste dann eine weitere Liste her, um die Kombinationen herzustellen. Anschließend ein weiteres leeres Wörterbuch erstellen, und dann muss eine weitere For-Schleife eingebaut werden. Und in der check_setions_options()-Funktion muss dann ebenfalls eine weitere For-Schleife hingesetzt werden. Fazit: 6 Schritte, sobald ein neuer Bereich und die dazugehörigen Optionen hinzukommt. Habt ihr Vorschläge, wie man das optimieren könnte?
DasIch
User
Beiträge: 2718
Registriert: Montag 19. Mai 2008, 04:21
Wohnort: Berlin

Dein Konzept ist sehr kompliziert und entsprechend schwer zu verstehen, dies merkt man dann auch am Code. Letzteren solltest du löschen, da du den erst gar nicht hättest schreiben sollen. Agile und Iterative Ansätze sind zwar toll aber du solltest schon ein gutes Design im Kopf haben dass du verstehst und verständlich vermitteln kannst. Kannst du ein Design anderen nicht erklären wirst du auch daran scheitern es in Code umzusetzen, den diese beiden Dinge sind letztendlich dasselbe.

Sofern ich dich verstanden habe hast du Konfigurationsdateien die bestimmte Sektionen mit bestimmten Optionen haben sollen. Du möchtest überprüfen können ob eine bestimmte Konfigurationsdatei tatsächlich alle erwarteten Sektionen hat und die Sektionen jeweils die dazugehörigen Optionen.

Das Format das deine Konfigurationsdateien haben sollen ist in deinem Code schon über die Objekte dict_sections, dict_options, section_general_list, section_gui_list, dict_sections_general und dict_sections_gui verteilt. 6 Objekte um ein Format zu beschreiben dass nur Sektionen kennt welche Optionen enthalten. Schon rein zahlenmäßig wird klar dass hier Chaos herrscht. Es ist nicht zu erkennen wie die Objekte vom Namen her in das Konzept passen und ganz allgemein sind die Namen schlecht gewählt, den Typen sollte man in Namen möglichst nicht erwähnen. Man könnte hier vielleicht auch noch über die Objekte an sich reden aber wir sind schon soweit weg vom Pfad dass man über die schon nicht mehr sinnvoll sprechen kann weil es da keine gute Alternative geben kann.

Es ist schwer bis unmöglich etwas brauchbares zustande zu bekommen wenn man auf etwas schlechtem aufbauen muss. Das ist dir dann im restlichen Code auch nicht gelungen, deswegen lohnt es sich auch hier keine Kritik weil auch es auch hier keine gute Lösung geben kann.

Das Format lässt sich ganz einfach repräsentieren: ``{SECTION_NAME: [OPTION]}``. Ein Dictionary, die Keys sind die Namen der Sektionen, die Values Listen mit Optionen. Lösch den Code den du schon hast und fang mit dieser Repräsentation neu an.
Sirius3
User
Beiträge: 18335
Registriert: Sonntag 21. Oktober 2012, 17:20

@Sophus: ich habe mal aus Deinem Code alles unnötige und doppelte rausgelöscht und in verständliche Variablennamen umbenannt. Variablennamen sollten möglichst keine Abkürzungen enthalten und nichtssagende Prä- oder Postfixe wie _gen. Strings sind keine Kommentare, wobei Kommentare auch beschreiben sollten, warum etwas gemacht wird, das wie kann man ja aus dem Code lesen. Am wichtigsten ist aber, dass Kommentare richtig sind. Die "Empty List" suche ich vergeblich. Leider kann ich Dein Problem nicht reproduzieren:

Code: Alles auswählen

import ConfigParser

CONFIG_OPTIONS = {
    'General_Configuration': ['language', 'database_type', 'dir_path_temp_folder',
        'url_update', 'time_out_update', 'last_folder_path_remeber'],
    'General_Design': ['gui_style', 'scheme_color'],
}

def check_setions_options(ini_path):
    config_setting = ConfigParser.SafeConfigParser()
    config_setting.read(ini_path)
    for section, options in CONFIG_OPTIONS.iteritems():
        print '(%s) section exists: %s' % (section, config_setting.has_section(section))
        for option in options:
            print '%s.%-12s  : %s' % (section, option, config_setting.has_option(section, option))

if __name__ == "__main__":
    path_to_ini_file = raw_input("Enter Path: ")
    check_setions_options(path_to_ini_file)
Benutzeravatar
Sophus
User
Beiträge: 1109
Registriert: Freitag 25. April 2014, 12:46
Wohnort: Osnabrück

@Sirius3 und @DasIch,

Mein Quelltext bzw. Skript wirkt in der Tat etwas unbeholfen. Das habe ich auch gemerkt, daher hoffte ich auf Optimierung. Aber um das Ganze nachvollziehbarer zu machen: Ich bin mir ziemlich sicher, dass ihr es bemerkt habt. Mit der generate_constants_sections_options()-Funktion wollte ich die Konstanten dort unterbringen. Ich weiß, für gewöhnlich schreibt man Konstanten in Großbuchstaben immer ganz oben - in der Nähe von den ganzen Imports, und das dann auf Modulebene. Warum ich das alles in eine Funktion packte, lag daran, weil ich merkte, dass ich sehr viele Wörterbücher und Listen angelegt habe. Warum nun zwei Wörterbücher (dict_sections / dict_options)? Das Skript, welches ich euch präsentiert habe, war schon eine sehr abgespeckte Version. Mir ging es daraum, dass ich an einer anderen Stelle im Skript eine Konfigurationsdatei erstelle, wenn keine vorhanden. Und so übergab ich der generate_constants_sections_options()-Funktion ein bestimmtest Argument, so dass er mir zum Beispiel nur das dict_sections-Wörterbuch rausgibt, damit ich zunächst die Sections erstellen kann usw.

Aber Sirius3' Vorschlag sieht wesentlich übersichtlicher aus. Ich werde versuchen damit zu arbeiten. Da ich nun in Sirius3' Variante nicht mehr direkt auf die Section-Namen zugreifen kann: Aus diesem Grund habe ich die Variante gewählt, dass im Schlüssel SECTION_GENERAL stand, und ich über den Schlüssel dann auf den Wert zugreifen kann, und somit den Namen der Section erhalte. In Sirius3' Variante kann ich nicht so einfach vorgehen, sondern muss dann wie folgt zugreifen:

Code: Alles auswählen

print "KEY [0]", CONFIG_OPTIONS.keys()[0]
print "KEY [1]", CONFIG_OPTIONS.keys()[1]
Komisch für mich ist an der Stelle, dass die Ausgabe wie folgt aussieht:
KEY [0] General_Design
KEY [1] General_Configuration
Komisch deshalb, weil der Schlüssel General_Configuration im von Sirius3' erstellten Wörterbuch an erste Stelle steht. Müsste nicht bei keys(0) der Schlüssel General_Configuration angezeigt werden, wenn man von oben nach unten liest?
Sirius3
User
Beiträge: 18335
Registriert: Sonntag 21. Oktober 2012, 17:20

@Sophus: keine Ahnung, was Du mit "direkt auf die Section-Namen zugreifen" meinst. Viele Wörterbücher mit genau einem Schlüssel machen jedenfalls keinen Sinn. Wenn Dir die Reihenfolge wichtig ist, nimm ein OrderedDict.
Benutzeravatar
Sophus
User
Beiträge: 1109
Registriert: Freitag 25. April 2014, 12:46
Wohnort: Osnabrück

@Sirius3:

Hier ein Wörterbuch:

Code: Alles auswählen

d = {'x': 5, 'y': 2, 'z': 3}
Nun habe ich viele Möglichkeiten. Ich kann über den Wert an einen Schlüssel gelangen. Aber das möchte ich nicht. Ich denke dabei eher an diese Liste. Man kommt über einen bestimmten Index an ein Element. Zum Beispiel:

Code: Alles auswählen

animals = ['bear', 'tiger', 'penguin', 'zebra']
print animals[0]
Über den Index 0 greife ich auf das entsprechende Element zu, also auf bear.

Und so habe ich es mir bei einem Wörterbuch vorgestellt. Denn ich möchte mit dem Namen des Schlüssels weiterarbeiten, denn der Name des Schlüssels ist ja auch gleichzeitig der Name meiner Section in der INI-Datei.

Nehme ich noch einmal das obere Wörterbuch:

Code: Alles auswählen

d = {'x': 5, 'y': 2, 'z': 3} 
print d.keys()[0]
Anstatt mir den Schlüssel namens x auszuspucken, bekomme ich den Schlüssel namens y. Und das verstehe ich nicht.
Sirius3
User
Beiträge: 18335
Registriert: Sonntag 21. Oktober 2012, 17:20

@Sophus: Wörterbücher haben keine Ordnung, daher kann man auch nicht auf den 1. Wert zugreifen, ich sehe auch nicht, wo Du das vermeindlicherweise benötigst.
Benutzeravatar
Sophus
User
Beiträge: 1109
Registriert: Freitag 25. April 2014, 12:46
Wohnort: Osnabrück

@Sirius3: Aus meinem Skript wird es auch nicht deutlich. Wie ich schon sagte, möchte ich mit den Namen der Schlüssel später arbeiten. Aber ich will nicht über den Wert suchen. Wenn ich also an einer anderen Stelle eine INI-Datei erstellen möchte, möchte ich einfach auf den Schlüssel zugreifen. Mit diesem Namen arbeite ich dann weiter. Das war auch der Grund, wieso mein Skript auch unübersichtlich wurde, da ich dann über den Schlüssel auf die Werte zugegriffen habe, da die Namen der Sectionen im Wörterbuch als Wert hinterlegt waren. In deinem Beispiel sind die Namen der Sections nicht mehr als Wert, sondern als Schlüssel. Und ich will jetzt gezielt an die Namen der Sections kommen.
Benutzeravatar
Sophus
User
Beiträge: 1109
Registriert: Freitag 25. April 2014, 12:46
Wohnort: Osnabrück

Ich glaube, ich bin der Sache etwas näher gekommen, wie man das Wörterbuch nach den Schlüssel sortieren kann. Ich habe mir diese collections-Dokumentation angeschaut.

Mein Quelltext sieht jetzt so aus:

Code: Alles auswählen

import ConfigParser
from collections import OrderedDict

CONFIG_OPTIONS = {
    'General_Configuration': ['language', 'database_type', 'dir_path_temp_folder',
        'url_update', 'time_out_update', 'last_folder_path_remeber'],
    'General_Design': ['gui_style', 'scheme_color'],
    #'Nando': ['Ben', 'Mam']
}
 
def check_setions_options(ini_path):
    config_setting = ConfigParser.SafeConfigParser()
    config_setting.read(ini_path)
    for section, options in CONFIG_OPTIONS.iteritems():
        print '(%s) section exists: %s' % (section, config_setting.has_section(section))
        for option in options:
            print '%s.%-12s  : %s' % (section, option, config_setting.has_option(section, option))

sort_result = OrderedDict(sorted(CONFIG_OPTIONS.items(), key=lambda t: t[0]))

print "Sorted Dict", sort_result 
print "KEY [0]", sort_result .keys()[0]


if __name__ == "__main__":
    path_to_ini_file = raw_input("Enter Path: ")
    check_setions_options(path_to_ini_file)
Allerdings habe ic ein kleines Verständnisproblem. Ich weiß, dass lambda eine anonyme Funktion ist. Aber hätte das nicht ausgereicht, um zu sortieren?

Code: Alles auswählen

result = OrderedDict(sorted(CONFIG_OPTIONS.items()))
Ich meine zu wissen, dass:

Code: Alles auswählen

sort_result = OrderedDict(sorted(CONFIG_OPTIONS.items(), key=lambda t: t[0]))
gesagt wird, dass hierbei nach Schlüssel sortiert werden soll. Würde bei lambda in der eckigen Klammer eine 1 stehen, würde alles nach den Werten sortiert werden. Das mit lambda wirkt daher wie Fingerübung. Oder aber ich habe es schlicht und ergreifend nicht verstanden.
Benutzeravatar
Sophus
User
Beiträge: 1109
Registriert: Freitag 25. April 2014, 12:46
Wohnort: Osnabrück

Hallo Leute,

ich bin dabei, meine INI-Datei zu modifizieren. Zunächst wird ja überprüft, ob es bestimmte Sectionen, und anschließend, ob es bestimmte Optionen gibt. Wenn die Ergebnisse nicht True sind, werden Sectionen und die dazugehörigen Optionen hinzugefügt. Allerdings bekomme ich beim Ausführen dieses Skripts eine Fehlermeldung - siehe am Ende dieses Beitrages. Das "Komische" an der Fehlermeldung ist, dass ich die Objekte mittels der type()-Methode "analysieren" lasse. Und die Print-Anweisungen geben aus, dass es sich hierbei um 'str', also Strings handelt. Aber die Fehlermeldung besagt ja, dass das Objekt option ein String sein muss? Ich bin verwirrt. Was übersehe ich wieder mal?

Code: Alles auswählen

import ConfigParser
from collections import OrderedDict

CONFIG_OPTIONS = {
    'General_Configuration': ['language', 'database_type', 'dir_path_temp_folder',
        'url_update', 'time_out_update', 'last_folder_path_remeber'],
    'General_Design': ['gui_style', 'scheme_color'],
}
 
def check_setions_options(ini_path):
    config_setting = ConfigParser.SafeConfigParser()
    config_setting.read(ini_path)
    for section, options in CONFIG_OPTIONS.iteritems():
        result_section = (config_setting.has_section(section))
        print "result_section", result_section
        if not result_section:
            config_setting.add_section(str(section))
        for option in options:
            result_option = (config_setting.has_option(section, option))
            if not result_option:
                print "What type is option", type(option)
                print "What type is section", type(section)
                config_setting.set(section, option)

   # write changes back to the config file
    with open(ini_path, "w") as config_file:
        config_setting.write(config_file)

if __name__ == "__main__":
    path_to_ini_file = raw_input("Enter Path: ")
Traceback (most recent call last):
File "D:\Dan\Python\xarphus\examples\check_sec_opt.py", line 80, in <module>
check_setions_options(path_to_ini_file)
File "D:\Dan\Python\xarphus\examples\check_sec_opt.py", line 38, in check_setions_options
config_setting.set(section, option)
File "C:\Python27\lib\ConfigParser.py", line 743, in set
raise TypeError("option values must be strings")
TypeError: option values must be strings
Sirius3
User
Beiträge: 18335
Registriert: Sonntag 21. Oktober 2012, 17:20

@Sophus: set braucht neben section und option auch noch ein value, es sei denn der ConfigParser wurde mit allow_no_value erzeugt. Solange Deine Optionen keine sinnvollen Defaultwerte haben, macht es auch keinen Sinn, die Optionen zu erzeugen, und wenn Du sinnvolle Defaultwerte hast, dann ist es üblich, diese zu benutzen, wenn man sie nicht angibt. Deine Funktion check_setions_options macht also weder so noch so Sinn, ist falsch geschrieben und hat den falschen Namen, weil sie ja mehr als check macht.
Benutzeravatar
Sophus
User
Beiträge: 1109
Registriert: Freitag 25. April 2014, 12:46
Wohnort: Osnabrück

@Sirius3: Vielen Dank. Du hattest Recht. Ich habe einfach die Werte vergessen. Das Skript per se ergibt in der Tat wenig Sinn. Mir geht es darum, wenn ich eine neue Software-Version einspiele, und ein Benutzer bekommt mehr Einstellungsmöglichkeiten, müssen diese ja auch gespeichert werden. Das führt also dazu, dass die vorherige Konfigurationsdatei nicht mehr aktuell ist, und daher fehlende Sectionen und Optionen hinzugefügt werden müssen.
DasIch
User
Beiträge: 2718
Registriert: Montag 19. Mai 2008, 04:21
Wohnort: Berlin

Gib der Konfigurationsdatei eine Versionsoption die dir erlaubt zu prüfen in welcher Version die Konfiguration vorliegt. Auf die Weise kannst du ohne Raten die Konfiguration richtig updaten.
Benutzeravatar
Sophus
User
Beiträge: 1109
Registriert: Freitag 25. April 2014, 12:46
Wohnort: Osnabrück

@DasIch: Inwiefern "rate" ich denn? Ich meine, mal davon abgesehen, dass meine Funktion falsche Namen hat, und man die Werte noch nicht eingetragen hat, wird die Konfigurationsdatei ja aktualisiert. Nicht? Es wird ja geschaut, ob Sectionen und Optionen vorhanden sind, wenn nicht, dann ist die Datei 'veraltet' bzw. entspricht nicht der Version des aktuellen Programms. Wieso also einen zusätzlichen Weg gehen, und erst die Version überprüfen?
Sirius3
User
Beiträge: 18335
Registriert: Sonntag 21. Oktober 2012, 17:20

@Sophus: dafür gibt es ja Default-Werte. Wenn eine neue Version mehr Optionen hat, dann haben die halt, solange sie nicht definiert sind, ihre Defaultwerte. Ich als Anwender will eigentlich nicht, dass irgend eine neue Version mir in meiner Konfiguration herummurkst.
Benutzeravatar
Sophus
User
Beiträge: 1109
Registriert: Freitag 25. April 2014, 12:46
Wohnort: Osnabrück

@Sirius3: Irgendwie erscheint mir das widersprüchlich. Wenn du eine neue Programmversion benutzt, und dort sind neue und weitere Einstellmöglichkeiten vorhanden. Dann will man schon, dass diese auch gespeichert werden, nicht? Wohin sollen diese dann? Also muss man unweigerlich die Konfigurationsdatei anpassen oder eben eine neue Datei erstellen? Das wäre aber unrentable.
Benutzeravatar
kbr
User
Beiträge: 1510
Registriert: Mittwoch 15. Oktober 2008, 09:27

@Sophus: Defaultwerte findest Du in Konfigurationsdateien üblicherweise in auskommentierter Form zusammen mit einer Beschreibung, was diese bewirken. Diese Defaultwerte sind Programmintern definiert und finden Verwendung, wenn keine anderen Werte in der Konfigurationsdatei gesetzt sind (bzw. gar nicht erst von dort gelesen werden konnten).
Insofern ist es gar kein Problem eine neue Programmversion mit einer alten Konfigurationsdatei zu betreiben; für neue Optionen werden dann eben deren Defaultwerte verwendet und der Nutzer muss dann die Konfigurationsdatei anpassen, wenn er von neuen Optionen, abweichend von deren Default-Einstellungen, Gebrauch machen möchte.
Benutzeravatar
Sophus
User
Beiträge: 1109
Registriert: Freitag 25. April 2014, 12:46
Wohnort: Osnabrück

@kbr: Ich verstehe dein Konzept: Aber was spricht denn dagegen, die Konfigurationsdatei gleich anzupassen? Immerhin werden die vorherigen Werte ja nicht verändert. Es werden ja nur neue Optionen und Sectionen hinzugefügt. All die anderen Einstellungen bleiben ja.
Sirius3
User
Beiträge: 18335
Registriert: Sonntag 21. Oktober 2012, 17:20

@Sophus: und was ist mit Kommentaren und Leerzeilen? Zudem ist es einfach nicht üblich, und widerspricht den Erwartungen vieler Anwender.
Antworten