2010-12-19 10 views
0

Ich versuche, eine Methode zu erstellen, um mehrere parametrisierte Konfigurationsdateiabschnitte zu einem zusammenzuführen.Objekte durch ihre Parameter suchen und zusammenführen

Jeder Abschnitt kann bestimmte Abschnittsparameter enthalten und enthält eine Nutzlast von Konfigurationsvariablen. Es ist ein Beispiel von einigen Sektionen:

[MySection] 
    foo = defaultbar 

[MySection|color=red|shape=circle] 
    foo = bar 
    variable = value 

[MySection|shape=circle] 
    otherfoo = otherbar 
    foo = anotherbar 

Diese Abschnitte sind durch folgende Klasse dargestellt:

class Section(): 
    # All values here are parsed from config file 
    name = "MySection" 

    # This is a section specific parameters 
    params = {'color': 'red', 
       'share': 'circle', 
       'weight': 'ton'} 

    # This is section variables payload 
    vars = {'foo': 'bar', 
      'variable': 'value'} 

    def merge(self, section): 
     """Merges current section vars with vars of given one""" 
     # ...code here... 

(Alle Parameter und Vars in der Laufzeit zugeordnet sind, nicht statisch zugewiesen) Abschnitt Parameter können variieren, einige können abwesend sein.

Was ich brauche, ist ein Algorithmus zum Auswählen und Zusammenführen von Konfigurationsabschnitten (seine variablen Nutzlasten) zu einem durch einen bestimmten Abschnitt Parameterwerte.

Zum Beispiel habe ich eine Liste der Sektionen:

sections[0].params = {'color': 'blue'} 

sections[1].params = {'shape': 'circle'} 

sections[2].params = {'color': 'red'} 

sections[3].params = {'shape': 'circle'} 

sections[4].params = {'color': 'blue', 
         'shape': 'circle'} 

sections[5].params = {'weight': 'ton'} 

sections[6].params = {'color': 'blue'} 

sections[7].params = {'color': 'blue', 
         'shape': 'circle', 
         'weight': 'ton'} 

Die Auswahl und Zusammenführen von Kriterien (bestimmt in Runtime) ist ein OrderedDict, zum Beispiel:

criteria = {'color': 'blue', 
      'shape': 'circle', 
      'weight': 'ton'} 

Jetzt muß ich suchen die Liste der Sektionen, um diejenigen zu finden, die diese Kriterien mindestens teilweise erfüllen. Abschnitte, die mehr Parameterübereinstimmungen haben, müssen später zusammengeführt werden.

sections[0] + sections[6] + sections[1] + sections[3] + sections[5] + 
sections[4] + sections[7] 

Reihenfolge der Zusammenführung ist wichtig, für die gleichen Parameter Abschnitte (zB 0 und 6, 1 und 3) Der generische Algorithmus mit einer möglichen Ausnahme:

Mit bestimmten Kriterien Abschnitten werden in folgenden Reihenfolge zusammengefügt werden ist:

  1. Suche nach Abschnitt, der nur den ersten Parameter von Kriterien haben und sie
  2. Wiederholen sie Schritt 1 für andere Parameter in Kriterien fusionieren
  3. Suche nach Abschnitt, der zwei Parameter von Kriterien erfüllt ... und so weiter ...

Gibt es eine schnelle und elegante Art und Weise, dies zu tun?

+1

'{'x' = 'y'}' ist keine gültige Python-Syntax. Um die Schlüssel/Wert-Paare eines Dik anzugeben, wollen Sie '{'x': 'y'}'. –

+2

Auch Wörterbücher ** haben keine Reihenfolge **, also können Sie nicht sagen, dass die Reihenfolge der Zusammenführung wichtig ist - es spielt keine Rolle, in welcher Reihenfolge Sie sie zusammengeführt haben, die resultierenden 'vars' wären die gleich. –

+1

Ja, mein schlechtes mit der Syntax. Mit "Reihenfolge der Zusammenführung ist wichtig" meinte ich, dass die Reihenfolge, in der section.merge() aufgerufen wird, wichtig ist (weil Abschnitt vars in einigen Fällen überschrieben wird). Jetzt sehe ich, dass "Kriterien" ein OrderedDict sein muss. – RedRampage

Antwort

0

Dies wird kombiniere sie, um mit dem letzten man die wichtigsten sind:

parameters = {} 
parameters.update(sections[0]) 
parameters.update(sections[6]) 
parameters.update(sections[1]) 
parameters.update(sections[3]) 
parameters.update(sections[5]) 
parameters.update(sections[4]) 
parameters.update(sections[7]) 

Es ist mir unklar, was man mit „Merging Kriterien“ bedeuten. Möglicherweise meinen Sie, dass einige Werte wichtiger sind als andere, aber dann gibt es keinen guten Weg, dies zu tun, außer dass Sie jeden Parameter selbst betrachten.

Update:

Nein, es gibt keine schnelle und elegante Art und Weise zu tun, was Sie wollen.

Zuerst müssen Sie Ihre Abschnitte danach sortieren, wie gut sie Ihren Merging-Kriterien entsprechen, die eine Liste von Schlüsseln und Werten sein müssen (OrderedDict funktioniert, aber auch eine Liste von Wörterbüchern oder Tupeln).Da Sie sich darum kümmern, wie eindeutig die Parameter bei der Übereinstimmung sind, müssen Sie die Anzahl der Parameter für den Abschnitt als Teil des Sortierschlüssels angeben.

Sie müssen dann die Abschnitte in dieser Reihenfolge nehmen und sie zusammenführen. Es gibt keine Problemumgehung, wirklich. :)

Es kann jedoch schnelle und elegante Wege geben, Ihren Anwendungsfall zu lösen, aber wir wissen nicht, dass Sie uns nicht sagen, warum Sie es tun. Vielleicht ist es auch eine Frage wert.

+0

Nun, ich habe versucht, einige Details im Hauptpost zu klären. – RedRampage

+0

@RedRampage: Aktualisiert. –

+0

Use-Case ist eine Art von Überlastung im Konfigurationsbereich. Einige benutzerdefinierte Parameter (z. B. Systemsprache oder Softwareversion) werden in der Laufzeit festgelegt und müssen beim Analysieren der Konfigurationsdatei berücksichtigt werden. Standardmäßig verwendet das Programm einen parameterlosen Abschnitt, aber wenn die Konfigurationsdatei einen Abschnitt enthält, der für diese benutzerdefinierten Parameter spezifisch ist, müssen Standardwerte durch ihren Inhalt überschrieben werden. – RedRampage

Verwandte Themen