delete delete

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
zulu321
gelöscht
Beiträge: 13
Registriert: Samstag 23. Januar 2010, 23:02

delete delete
Zuletzt geändert von zulu321 am Sonntag 18. April 2010, 18:26, insgesamt 2-mal geändert.
BlackJack

@zulu321: Mir scheint Du solltest Dich noch einmal mit den Grundlagen von objektorientierter Programmierung auseinandersetzen.

Der `run()` kann man keine Argumente mitgeben, aber beim Aufruf von `Rechne()` könntest Du das zum Beispiel machen.

Bei dem ``while`` könntest Du statt dem `True` auch gleich die passende Bedingung mit dem Event schreiben, dann fällt das ``if`` weg.
zulu321
gelöscht
Beiträge: 13
Registriert: Samstag 23. Januar 2010, 23:02

delete delete
Zuletzt geändert von zulu321 am Sonntag 18. April 2010, 18:26, insgesamt 1-mal geändert.
Leonidas
Python-Forum Veteran
Beiträge: 16025
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

Verbesserungsvorschläge: Die gesamte Klasse Main ist für die Tonne - einfach weglassen.

Dann: ``while`` nimmt neben ``True`` auch Bedingungen entgegen, da kannst du dann auch das ``if`` loswerden. Ach, das hat BlackJack schon gesagt? Naja, scheint dir ja entgangen zu sein.

Wozu du zwei Klassen von ``threading.Thread`` ableitest ist mir auch vollkommen unklar. Und die Subklasse von ``Thread`` dann einfach ``Thread`` zu nennen ist fast schon, naja, dreist.

``Funktionen`` ist kein brauchbarer Klassenname und ich habe das Gefühl dass da aus OOP-Sicht ziemlich was falschgelaufen ist.

So und nun ist spät und ich geh schlafen :)
My god, it's full of CARs! | Leonidasvoice vs (former) Modvoice
BlackJack

@zulu321: Selbst wenn das ``if`` noch mehr Bedingungen enthält, können die doch alle entsprechend formuliert ins ``while`` verschoben werden!? Falls anstelle des ``break`` da noch mehr steht, müssten das dann hinter der Schleife stehen.

Ansonsten ist es bei so einem "eingedampften" Beispiel natürlich nicht immer leicht Ratschläge für die echte Anwendung zu geben. So wie's da steht macht es zum Beispiel den Eindruck, als wenn zu viele Klassen verwendet werden. Die `Menu`-Klasse zum Beispiel ist hier komplett überflüssig und könnte durch eine Funktion ersetzt werden.

Bei der Namensgebung sollte man nicht Englisch und Deutsch mischen wenn sich das vermeiden lässt. Abkürzungen sollte man möglichst vermeiden, wenn sie nicht ziemlich verbreitet sind, und jeder weiss was sie bedeuten. Bei `start_fkt` und `stop_fkt` sind sie sowieso redundant denn die Klasse heisst ja schon `Funktionen`. `Funktionen.start_funktion()` hat IMHO keinen Informationsmehrwert gegenüber `Funktionen.start()`.

Bei solchen ``if``/``elif``-Kaskaden, die man in anderen Sprachen mit einem ``switch``- oder ``case``-Konstrukt schreiben würde, bieten sich in Python Dictionaries an:

Code: Alles auswählen

def main():
    
    funktionen = Funktionen()
    dispatch = {
        'a': funktionen.start,
        'b': funktionen.stop,
        'c': functools.partial(sys.exit, 1)
    }
    
    def illegal_input():
        print 'Illegale Eingabe!'

    while True:
        dispatch.get(raw_input('->'), illegal_input)()
Das Beispiel fängt jetzt schon Eingaben ab zu denen keine Aktionen vorgesehen sind. Man muss bei Benutzern immer sehr vorsichtig sein, die halten sich nicht immer an vorgegebene Wege, also müsste man auch dafür sorgen, dass der Benutzer nicht zweimal hintereinander 'a' wählt solange der Thread noch läuft.
zulu321
gelöscht
Beiträge: 13
Registriert: Samstag 23. Januar 2010, 23:02

delete delete
Zuletzt geändert von zulu321 am Sonntag 18. April 2010, 18:26, insgesamt 1-mal geändert.
BlackJack

@zulu321: Selbst wenn's nur für Dich ist, sollten schon gewisse Fehleingaben behandelt werden. Wenn Du zum Beispiel zweimal hintereinander 'a' eingibst, hast Du keinen direkten Zugriff mehr auf den ersten "DNS-Thread" und kannst den nicht mehr stoppen.

Ich hab's übrigens gerade in einem anderen Thread schon einmal empfohlen: Das `cmd`-Modul in der Standardbibliothek stellt ein kleines Rahmenwerk für solche interaktiven Kommandozeilenprogramme bereit. Wenn man zum Parsen von Argumenten dann noch das `shlex`-Modul benutzt und zumindest unter Unixoiden Systemen `readline` importiert, kann man damit relativ einfach doch recht komfortable kleine Kommandoshells implementieren.

Die Konventionen für Klassennamen sind bei Python übrigens die gleichen wie bei Java. Die Streitigkeiten fangen erst bei den anderen Bezeichnern an. :-)

Von der Trennung von UI und Logik bin ich noch nicht so recht überzeugt. IMHO ist in `dnsReply` noch beides vermischt.

``sys.exit(1)`` ruft `sys.exit()` mit dem Argument 1 auf. `functools.partial(sys.exit, 1)` ruft `functools.partial()` mit der Funktion `sys.exit()` und einer 1 als Argumente auf und gibt eine Funktion zurück, die wenn man sie aufruft, die übergebene Funktion mit den ebenfalls übergebenen Argumenten aufruft. Plus die Argumente, die man beim Aufruf des Rückgabewertes von `functools.partial()` angibt. Klassisches Beispiel ist eine "adder"-Funktion bei der man einen Teil der Argumente bindet:

Code: Alles auswählen

In [408]: def add(a, b):
   .....:     return a + b
   .....:

In [410]: add(23, 42)
Out[410]: 65

In [411]: add23 = functools.partial(add, 23)

In [412]: add23
Out[412]: <functools.partial object at 0xcc59a04>

In [413]: add23(42)
Out[413]: 65

In [414]: add23(0)
Out[414]: 23

In [415]: add23(10)
Out[415]: 33
Oder eben genau das Codebeispiel:

Code: Alles auswählen

In [417]: sys.exit(1)
---------------------------------------------------------------------------
<type 'exceptions.SystemExit'>            Traceback (most recent call last)

/home/bj/<ipython console> in <module>()

<type 'exceptions.SystemExit'>: 1
Type %exit or %quit to exit IPython (%Exit or %Quit do so unconditionally).

In [418]: f = functools.partial(sys.exit, 1)

In [419]: f()
---------------------------------------------------------------------------
<type 'exceptions.SystemExit'>            Traceback (most recent call last)

/home/bj/<ipython console> in <module>()

<type 'exceptions.SystemExit'>: 1
Type %exit or %quit to exit IPython (%Exit or %Quit do so unconditionally).
zulu321
gelöscht
Beiträge: 13
Registriert: Samstag 23. Januar 2010, 23:02

delete delete
Zuletzt geändert von zulu321 am Sonntag 18. April 2010, 18:26, insgesamt 1-mal geändert.
EyDu
User
Beiträge: 4881
Registriert: Donnerstag 20. Juli 2006, 23:06
Wohnort: Berlin

zulu321 hat geschrieben:Wie kann ich bei der Dispatcher-Variante mehrere Funktionen aufrufen? So wie ich es in test1.py versucht habe funktioniert es leider nicht.
Dann schau dir doch mal die Fehlermeldung an. Die sagt schon recht genau, was dort nicht passt ;-)

Das != 1 in Zeile 50 kannst du übrigens durch ein not ersetzen.
Das Leben ist wie ein Tennisball.
zulu321
gelöscht
Beiträge: 13
Registriert: Samstag 23. Januar 2010, 23:02

delete delete
Zuletzt geändert von zulu321 am Sonntag 18. April 2010, 18:27, insgesamt 1-mal geändert.
EyDu
User
Beiträge: 4881
Registriert: Donnerstag 20. Juli 2006, 23:06
Wohnort: Berlin

Ok, ich meine den Fehler mit

Code: Alles auswählen

dispatch = {
        'a': (dns.start, print "ip1: " + dns.get_info("ip1"),)
        'b': (dns.stop,)
        'c': (functools.partial(sys.exit, 1))
    }
Beim Aufruf von c gibt es noch einen Fehler, darauf solltest du aber alleine kommen.
Das Leben ist wie ein Tennisball.
zulu321
gelöscht
Beiträge: 13
Registriert: Samstag 23. Januar 2010, 23:02

delete delete
Antworten