2017-09-07 8 views
2

Ich habe eine Klasse Test mit Attributen Test.att1, Test.att2, ..., Test.att10. Ich habe eine Methode Test.update(), die zehn neue Werte vals = [v1, v2, ... , v10] berechnet. Ich möchte Test Attribute in einer einzigen for-Schleife aktualisieren.Aktualisieren mehrerer Attribute Python

Ich stelle mir so etwas wie das Durchlaufen der Liste mylist = [self.att1, self.att2, ... , self.att10] innerhalb der Test Klasse und Einstellwerte pro vals vor, aber das schien nicht zu funktionieren. Was kann ich stattdessen tun/was ist der beste Weg, um mehrere Attribute ohne eine self.att1, self.att2, self.att3 = v1, v2, v3 Struktur zu aktualisieren?

EDIT: Ich frage speziell, weil ich etwas tue, wie:

a1, a2, a3, a4, a5 = self.update() 
self.a1 = pd.concat([self.a1, a1]).drop_duplicates().reset_index(drop=True) 
self.a2 = pd.concat([self.a2, a2]).drop_duplicates().reset_index(drop=True) 
self.a3 = pd.concat([self.a3, a3]).drop_duplicates().reset_index(drop=True) 
self.a4 = pd.concat([self.a4, a4]).drop_duplicates().reset_index(drop=True) 
self.a5 = pd.concat([self.a5, a5]).drop_duplicates().reset_index(drop=True) 

und bin derzeit mit Ein rückwärts Weg endete ich dies bis zu tun war:

def update(self): 
    dfs = [self.att1, self.att2, ..., self.att10] 
    dfs = [pd.concat([dfs[i], vals[i]]).drop_duplicates().reset_index(drop=True) \ 
       for i in range(len(dfs))] 
    [self.att1, self.att2, ..., self.att10] = dfs 

aber bei der Suche nach ein besserer Weg

+0

Warum schreiben Sie nicht eine Methode, die die Liste übernimmt und die Attribute aktualisiert? Auf diese Weise wird es dir leichter fallen. –

+0

Sie alle teilen eine ähnliche Struktur in der Art von 'pd.concat ([self.att1, df]). Drop_duplicates(). Reset_index (drop = True)' Also habe ich mich gefragt, wie ich nur einmal schreiben und 10 Mal vermeiden sollte ... – jjjjjj

Antwort

1

Sie könnten setattr in Kombination mit hasattr verwenden, um Attribute zum Zielobjekt zu aktualisieren und hinzuzufügen.

attrs = [a for a in dir(Test) if a.startswith('attr') and 'no_update' not in a] 

### To update existing attrs ### 
new_vals = [...] 
for a, v in zip(attrs, new_vals): 
    if hasattr(Test, a): 
     setattr(Test, a, v) 

### To add new attrs ### 
new_vals = [...] 
start = int(attrs[-1][4:]) + 1 # the number the new attrs should start at 
new_attrs = ['attr%d' % n for n in range(start, start+len(new_vals))] # if start==4 and len(new_vals)==3: return ['attr5', 'attr6', 'attr7'] 
for a, v in zip(new_attrs, new_vals): 
    setattr(Test, a, v) 

Diese können auch kombiniert werden, um vorhandene Attribute zu aktualisieren und gegebenenfalls neue zu setzen.

+0

Danke! Was ist, wenn ich 'v' anfügen möchte, um' a' gemäß meinem Update zu kennzeichnen? Ist das noch ein sauberer Weg? – jjjjjj

+0

Damit meinen Sie die Verkettung des neuen und alten Attr-Wertes? Wenn das der Fall ist, können Sie den Attr einfach so "abholen", wie Sie 'setzen' können und prüfen, ob es so aussieht:' setattr (Test, a, getattr (Test, a) + v) ' – Nelson

+0

Grundsätzlich sind diese Attribute Pandas DataFrames, und ich möchte neue Zeilen zu einem bestehenden 10 oder so DataFrames hinzufügen, die ich als Attribute von "Test" habe, aber ich habe auch andere Attribute 'att_no_update1', ...' att_no_update10', die ich nicht will update – jjjjjj