2016-10-10 1 views
1

Mir wurde gesagt, dass ich vermeiden sollte, self.__dict__ in meinem Code zu verwenden, aber ich kann nicht anders herum finden für das, was ich versuche zu tun. Ich fange gerade an, mit Klassen zu arbeiten, also nicht so sicher, wie man das macht.So vermeiden Sie die Verwendung von selbst .__ dict__ in einer Klasse

class variable(object): 
    def __init__(self, json_fn, *args, **kwargs): 

     self.metrics = self.getmetrics(json_fn) 
     for metric in self.metrics : 
      self.__dict__[metric] = self.get_metric_dataframes(metric) 

    def get_metric_dataframes(self , metric_name): 
     '''extract and return the dataframe for a metric''' 

Also mein Objekt "Variable" hat verschiedene Datenrahmen für verschiedene Metriken im JSON gespeichert. Ich wollte tun variable.temperature zu können, variable.pressure, variable.whatever ohne schreiben:

all
self.temperature = self.get_metric_dataframes(temperature) 
self.pressure = self.get_metric_dataframes(pressure) 
self.whatever = self.get_metric_dataframes(whatever) 

Da der Datenrahmen mit der gleichen Funktion der Metrik als Argument nehmen extrahiert werden. Welches ist, warum ich durch die Metriken geschlungen und verwenden

self.__dict__[metric] = self.get_metric_dataframes(metric)

Zu wissen, So dass ich nie eine dieser Datenrahmen aktualisieren (ich benutze eine Kopie davon in dem Code, wollen aber nicht die Werte der aktualisieren Objekt).

Gibt es eine andere Lösung?

Der andere Weg wäre ich tun könnte eine Dictionnary mit all metrischen als Schlüssel und Datenrahmen als Wert und speichern sie in self.metric zu bauen, kann ich es dann mit object.metric['temperature'] nennen, aber ich würde object.temperature sofort lieber tun, und ich bin irgendwie neugierig, ob das möglich ist.

Vielen Dank für Ihre Hilfe!

+0

Sie könnten fähig, 'setattr()' zu verwenden, aber ich bin nicht sicher, warum dir gesagt wurde, 'self .__ dict__' zu vermeiden. – kindall

Antwort

3

bereitgestellt jeder metric ein String ist, können Sie setattr anstelle einer direkten Zugriff auf die Instanz-Lexikon nutzen:

for metric in self.metrics: 
    setattr(self, metric, self.get_metric_dataframes(metric)) 
+1

Danke, dass es genau das ist, was ich gesucht habe – User18981898198119

1

Es gibt mehrere Lösungen:

  • mit __getattr__ aber Sie können laufen in Schwierigkeiten (Implementierung kann nicht trivial sein)
  • Verwendung von Eigenschaften: elegante und klassische Lösung,
  • mit Deskriptoren: kann schwierig zu debuggen sein, wenn Sie sich mit diesem vertraut sind.

Endlich ist Ihre Lösung mit __dict__ ziemlich gut. Sie können auch getattr/setattr verwenden.

Eine andere Lösung ist Ihre Messwerte in Ihrem eigenen dict zu speichern:

self.metric_dict = {metric: self.get_metric_dataframes(metric) for metric in metrics} 

Und dann Eigenschaften definieren dieses Wörterbuch zugreifen wie Attribute

@property 
def temperature(self): 
    return self.metric_dict["temperature"] 

Und so weiter ...

+0

Das scheint etwas mehr Arbeit zu sein als Moses 'Antwort, aber das ist auch ein interessanter Weg, danke, ich werde etwas tiefer hineinschauen. – User18981898198119

Verwandte Themen