Ausstieg aus Klassen OOP

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
lnix
User
Beiträge: 4
Registriert: Dienstag 6. September 2016, 09:11

Hallo Zusammen,

ich beschäftige mich neu mit der OOP in Python und komme irgendwie nicht weiter. Ich rufe eine Klasse auf und möchte, dass im Fehlerfall der Aufruf aussteigt, allerdings alle weiteren Aufrufe ausgeführt werden:

Code: Alles auswählen

print Parameter("hoost","servera.example.com").get("systemowner")
print Parameter("host","serverb.example.com").get("systemowner")

Hier die Klasse:

Code: Alles auswählen

42 class Parameter(Sat):
 43
 44     def __init__(self, form, form_name = None):
 45         # form: hostgroup, global, subnet, etc.
 46
 47         Sat.__init__(self)
 48         self.form_name = form_name
 49
 50         # declare input form and
 51         # repair form
 52         if form in [ "host" ]:
 53             self.form = "hosts"
 54         elif form in [ "hg" , "hostgroup" ]:
 55             self.form = "hostgroups"
 56         elif form in [ "common", "global", "gl", "gl_" ]:
 57             self.form = "common"
 58         else:
 59             self.form = form
 60
 61         # check valid form
 62         valid_forms = [ "hosts", "hostgroups", "common" ]
 63         if not self.form in valid_forms:
 64             print "Error: " + form + " is not a valid type. Please use a valid form like " + str(valid_forms)
 65             sys.exit(1)
 66
 67         if not self.form == "common":
 68             if not self.form_name:
 69                 print "Error: For the form " + self.form + " you have to input a searching name"
 70                 sys.exit(1)
 71
 72
 73     def get_form_id(self):
 74         if self.form == "hosts":
 75             post_url = "/api/" + self.form + "/" + self.form_name
 76             result = Sat.get_results(self, post_url)
 77             if result:
 78                 return result.get('id')
 79         else:
 80             post_url = "/api/" + self.form + "?search=" + self.form_name
 81             result = Sat.get_results(self, post_url)
 82             if result:
 83                 if not len(result) == 1:
 84                     print "Error: Too many results for " + self.form_name + " . Please use the exact name!"
 85                 else:
 86                     return result[0].get('id')
 87             else:
 88                 print "Error: Nothing found for " + self.form_name
 89
 90
 91     def get(self, parameter):
 92         if self.form == "common":
 93             self.post_url = "/api/common_parameters/" + parameter
 94         else:
 95             form_id = Parameter.get_form_id(self)
 96             self.post_url = "/api/" + self.form + "/" + str(form_id) + "/parameters/" + parameter
 97         return Sat.get_results(self, self.post_url)


Fragen:
1. Gibt es eine Lösung wie ich anstatt mit sys.exit(1) aussteige, damit der zweite Aufruf ausgeführt wird
2. Ist es ratsam sowas in __init__ zu machen?
3. Gerne weitere Anmerkungen.

[
Danke
Viele Grüße
lnix
Sirius3
User
Beiträge: 17753
Registriert: Sonntag 21. Oktober 2012, 17:20

sys.exit sollte außerhalb der Hauptfunktion (main) nicht vorkommen. Du willst an den Stellen einfach mit raise eine Exception werfen. Statt der if-from-in-Kaskade würde ich mit einem Wörterbuch arbeiten.
`not a == b` ist besser `a != b`, `not a in b` ein `a not in b`.
Statt Strings mit + zusammenzustückeln nimmt man Stringformatierung.
Da `get_results` nicht überschrieben wird, einfach statt `Sat.get_results` `self.get_results` aufrufen.
Warum wird mal post_url an self gebunden und mal nicht?
lnix
User
Beiträge: 4
Registriert: Dienstag 6. September 2016, 09:11

Danke für deine Antwort Sirius3.

sys.exit() habe ich herausgeworfen und raise implementiert. Allerdings bricht das Script sofort nach dem raise ab.

Wie meinst du das mit dem Wörterbuch?

Die Strings habe ich nun mit .format geändert.

Wenn ich statt Sat.get_results self.get_results aufrufe bekomme ich eine Fehlermeldung

Code: Alles auswählen

Traceback (most recent call last):
  File "sat6m.py", line 114, in <module>
    print Parameter("host","serverb.example.com").get("systemowner")
  File "sat6m.py", line 98, in get
    form_id = Parameter.get_form_id(self)
  File "sat6m.py", line 84, in get_form_id
    result = self.get_results(self, post_url)
TypeError: get_results() takes exactly 2 arguments (3 given)
Ich weiß nicht genau, ob ich self post_url an self binden muss?

Hier die Klasse

Code: Alles auswählen

48 class Parameter(Sat):
 49
 50     def __init__(self, form, form_name = None):
 51         # form:hostgroup, global, subnet, etc.
 52
 53         Sat.__init__(self)
 54         self.form_name = form_name
 55
 56         # declare input form and
 57         # repair form
 58         if form in [ "host" ]:
 59             self.form = "hosts"
 60         elif form in [ "hg" , "hostgroup" ]:
 61             self.form = "hostgroups"
 62         elif form in [ "common", "global", "gl", "gl_" ]:
 63             self.form = "common"
 64         else:
 65             self.form = form
 66
 67         # check valid form
 68         valid_forms = [ "hosts", "hostgroups", "common" ]
 69         if not self.form in valid_forms:
 70             raise NameError('{form} is not a valid type name!'.format())
 71
 72         if not self.form == "common":
 73             if not self.form_name:
 74                 raise SatException('For the form {} you have to input a searching name'.format(self.form))
 75
 76     def get_form_id(self):
 77         if self.form == "hosts":
 78             post_url = '/api/{}/{}'.format(self.form,self.form_name)
 79             result = Sat.get_results(self, post_url)
 80             if result:
 81                 return result.get('id')
 82         else:
 83             post_url = '/api/{}/?search={}'.format(self.form,self.form_name)
 84             result = Sat.get_results(self, post_url)
 85             if result:
 86                 if not len(result) == 1:
 87                     raise SatException('Too many results for {}. Please use the exact name!'.format(self.form_name))
 88                 else:
 89                     return result[0].get('id')
 90             else:
 91                 print SatException('Nothing found for {}'.format(self.form_name ))
 92
 93
 94     def get(self, parameter):
 95         if self.form == "common":
 96             self.post_url = '/api/common_parameters/{}'.format(parameter)
 97         else:
 98             form_id = Parameter.get_form_id(self)
 99             self.post_url = '/api/{}/{}/parameters/{}'.format(self.form,str(form_id),parameter)
100         return Sat.get_results(self, self.post_url)

__deets__
User
Beiträge: 14542
Registriert: Mittwoch 14. Oktober 2015, 14:29

Das sind wirklich Dinge, die in jedem absoluten Grundlagen-Tutorial erklaert werden. Sowohl, wie man mit Exceptions umgeht, als auch Methoden auf Objekten aufruft, warum da self steht in der Signatur, aber man es beim Aufruf nicht angeben muss. Hast du dir sowas mal angeschaut?
__deets__
User
Beiträge: 14542
Registriert: Mittwoch 14. Oktober 2015, 14:29

Noch ein paar Anmerkungen:

- sowas wie Sat.get_result(self, ...) funktioniert, ist aber so nicht gedacht. Ein simples self.get_result reicht, und wenn man das so macht gibt es auch keine Konfusion, wenn man das an anderer Stelle anders machen will.
- wenn etwas auf Ungleicheit geprueft werden soll, gibt es dafuer !=. not a == b ist bestenfalls ungewoehnlich, eher verwirrend.
- es sieht nicht so aus, als ob die Ableitung von Sat sinnvoll waere. Du benutzt ein Sat Objekt, aber es sieht nicht so aus, als ob dein Parameter-Objekt das Verhalten der Oberklasse irgendwie beeinflussen wuerde. Darum ist die Vererbung auch nicht notwendig. Ein Instanz-Attribut (self._sat = Sat(...)) oder im Zweifel sogar einfach nur ein neues Objekt in jeder deiner Methoden die du brauchst reicht.
- Sirius3 hat es schon angemerkt, ich tu's auch nochmal: post_url mal lokal, mal auf der Instanz ist ein Code-Smell. Ich sehe nirgendwo eine Verwendung von self.post_url ausserhalb der Methode wo es auch angelegt wird - es kann also aller Wahrscheinlichkeit nach auch genau da als lokale Variable bleiben.
Antworten