Alle Variablen einer Klasse ändern

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.
Antworten
RubenRybnick
User
Beiträge: 2
Registriert: Mittwoch 26. April 2017, 13:39

Hallo,

ich habe ein komisches Problem. Ich habe eine Klasse z.B.

Code: Alles auswählen

class parameter:
  a=2
  b=[1,2,3]
  c=4
....
usw.
im Prinzip eine Klasse voll mit Variablen, welche nur Zahlen angeben. Jedoch sind manche dieser Variablen schlecht deklariert und ich hätte sie gerne als np.array.

Gibt es eine Möglichkeit alle Einträge einer Klasse durchzugehen und diese zu ändern? Ich könnte jetzt händisch hinschreiben und wenn ich meiner Funktion die parameter Übergeben habe schreiben:

Code: Alles auswählen

def brot(parameter):
 parameter.b=np.array(b)
usw.

Gibt es eine Möglichkeit für alle durchzuführen?
Zuletzt geändert von Anonymous am Montag 17. Juli 2017, 15:03, insgesamt 1-mal geändert.
Grund: Quelltext in Python-Codebox-Tags gesetzt.
BlackJack

@RubenRybnick: Das ist ja erst einmal eine komische Klasse. Warum missbrauchst Du eine Klasse für so etwas? Wenn das ein Wörterbuch wäre, hättest Du das Problem nicht.

Man könnte mit `dir()` durch die Attribute/Werte gehen und die ”magischen” rausfiltern, und mit `setattr()` die Änderungen wieder auf dem Objekt speichern.
RubenRybnick
User
Beiträge: 2
Registriert: Mittwoch 26. April 2017, 13:39

Hoi,

der Code war leider schon vorhanden und ich muss mich irgendwie damit abfinden. Es sind ca 5000 Zeilen Code mit Verwendung von parameter.variable und den ganzen Code zu ändern ist mir zu Stressig. Ich könnte in der Klasse selber überall np.array davor schreiben, aber ich dachte es gibt vllt eine einfache Möglichkeit um das ganze automatisiert durchzugehen :(
nezzcarth
User
Beiträge: 1632
Registriert: Samstag 16. April 2011, 12:47

RubenRybnick hat geschrieben: der Code war leider schon vorhanden und ich muss mich irgendwie damit abfinden. Es sind ca 5000 Zeilen Code mit Verwendung von parameter.variable und den ganzen Code zu ändern ist mir zu Stressig. Ich könnte in der Klasse selber überall np.array davor schreiben, aber ich dachte es gibt vllt eine einfache Möglichkeit um das ganze automatisiert durchzugehen :(
Die "Klasse" zur Laufzeit (und damit bei jeder Ausführung neu!) so zurecht zu biegen, dass sie deinen Ansprüchen eher entspricht, ist meiner Meinung nach kein sinnvolles Vorgehen. Du solltest das nach Möglichkeit wirklich im Quelltext direkt abändern, auch wenn es einmalig viel Arbeit ist. Je nach Art und Umfang der Änderungen kann man das auch (semi-)automatisch machen, also z. B. mit regulären Ausdrücken in sed bzw. der Ersetzen-Funktion deines bevorzugten Editors, oder den Refactoring-Tools einer IDE wie Pycharm. Gerade die erstgenannte Variante ist natürlich nicht unkritisch, aber in solchen Fällen kann man das denke ich ausnahmsweise mal machen, wenn man vorsichtig ist.

Wenn es unbedingt sein muss, klappt es so, wie BlackJack meinte; statt dir kann man auch inspect.getmembers() zur Hilfe nehmen.
Zizibee
User
Beiträge: 229
Registriert: Donnerstag 12. April 2007, 08:36

Ich würde für so etwas die Suche und Ersetzte Funktion vom Notepad++ benutzen. Wenn man da ein Häckchen bei Reguläre Ausdrücke setzt, kann man sich da echt austoben :)
Bei deinem Beispiel in etwa so:

Suche: =[ ]?([a-zA-Z0-9 ,\[\]\(\)]*)
Ersetze: =np.array\(\1\)
BlackJack

Etwas sicherer als reguläre Ausdrücke wäre es wahrscheinlich auf dem AST von dem Quelltext zu operieren. `redbaron` ist für Python so etwas ähnliches wie BeautifulSoup für HTML:

Code: Alles auswählen

from __future__ import absolute_import, division, print_function
from redbaron import RedBaron
from redbaron.nodes import ListNode

SOURCE = '''
class Spam:
  x=[1,2,3]

class parameter:
  a=2
  b=[1,2,3]
  c=4
  d=[
    42,
    23,
    4711,
  ]

class Parrot:
  y=[3,2,1]
'''


def is_list_node(node):
    return isinstance(node, ListNode)


def main():
    np_array_call = RedBaron('np.array()')[0]
    red = RedBaron(SOURCE)
    parameter_class = red.find('class', name='parameter')
    for assignment in parameter_class('assignment', value=is_list_node):
        new_value = np_array_call.copy()
        new_value.call.value = assignment.value
        assignment.value = new_value
    print(red.dumps())


if __name__ == '__main__':
    main()
Ausgabe:

Code: Alles auswählen

class Spam:
  x=[1,2,3]

class parameter:
  a=2
  b=np.array([1,2,3])
  c=4
  d=np.array([
    42,
    23,
    4711,
  ])

class Parrot:
  y=[3,2,1]
Antworten