Seite 2 von 2

Verfasst: Samstag 2. Januar 2010, 11:58
von BlackJack
@maxi_king_333: Die Namen von *Klassen* sollten gross geschrieben werden. `Tkinter` ist doch keine Klasse, sondern ein Modul. Und bei dem `socket`-Beispiel binde ich nicht das Modul `socket` an den Namen `Socket`, sondern die Klasse `socket` *aus* diesem Modul. Interessanterweise heist die Klasse ursprünglich `_socketobject` und wird erst nachträglich an den Namen `socket` gebunden:

Code: Alles auswählen

In [137]: socket.socket
Out[137]: <class 'socket._socketobject'>
Die Komplexität wird *jetzt* noch nicht gebraucht. Auf die Objekte in den Dictionaries wird nicht zugegriffen, also kann man sie auch weglassen.

Und ich versteh's immer noch nicht. Mir ist klar, dass man für verschiedene Ereignisse, die man Melden möchte, jeweils Objekte benötigt, die diese Verarbeiten, den Benutzer informieren, oder auch andere Aktionen auslösen. Aber warum muss man die in diese Dictionaries stecken? Warum mit Zufallszahlen als Schlüssel? Wie soll man da je wieder *gezielt* herankommen? Und wenn man das nicht kann, warum stecken die dann nicht einfach in Listen? Warum willst Du da später noch einmal drauf zugreifen? Gib doch mal bitte ein konkretes Beispiel.

Das mit `Thread` kann man so schreiben, aber ich würde in dem Fall die Schlüsselworte explizit hinschreiben, statt Platzhalterargumente anzugeben.

Code: Alles auswählen

In [141]: def say_hello(to):
   .....:     print 'Hello, %s!' % to
   .....:

In [142]: t = threading.Thread(target=say_hello, args=['world'])

In [143]: t.start()

Hello, world!
Die Frage mit der Klasse habe ich nicht verstanden!? Man kann in Klassen auf alle Namen zugreifen, die auf Modulebene bekannt sind.

Das Problem mit `recv()` ist, dass die Gegenseite 'test\ntest1\n' nicht an einem Stück senden muss, sondern bei Dir auch bei einem `recv()`-Aufruf 'test\nte' und beim nächsten dann erst 'st1\n' ankommen kann. Es ist nicht wirklich garantiert, dass die Zeilen immer an einem Stück ankommen.

Das mit dem `dict()` in `parse.run()` hat einmal den Vorteil, dass `run()` nicht so gross wird und zum zweiten kann man es dann leichter erweitern. Das ist ausserdem die "pythonische" Art eine ``switch``-Anweisung auszudrücken, die es in anderen Programmiersprachen gibt. Ich würde an der Stelle wohl einen dynamischen "dispatch" anhand von ``info[1]`` machen, sofern man davon ausgehen kann, dass für die Fälle, die man behandeln möchte, immer etwas steht, was als Suffix eines gültigen Namens in Python durchgeht. Ungetestet: http://paste.pocoo.org/show/161268/

Nur um sicher zu gehen: Du weisst, dass die `Thread`-Objekte solange existieren, bis sie durchgelaufen sind? Auch wenn man keine Referenzen mehr darauf hält. Solange das Hauptprogramm läuft, braucht man sich da nicht mehr weiter zu kümmern. Für das Verhalten wenn das Hauptprogramm endet und noch Threads laufen, ist `Thread.setDaemon()` auf den jeweiligen `Thread`-Exemplaren. verantwortlich.

Verfasst: Samstag 2. Januar 2010, 12:17
von Dav1d
BlackJack hats zwar schon gesagt...
mit recv() bekommt man nicht immer komplette Zeilen! es kann einem passieren das erst mit dem nächsten Zeilenblock die Zeile beendet wird, zum Beispiel durch \r\n
\r\n war ein Beispiel

recv() empfängt immer Datenblöcke, allerdings kennt recv() den Delimiter nicht. Ein Beispieltext der gesendet wird:

Code: Alles auswählen

Hallo ich\r\n
bin ein Beispiel\r\n
Text mit unsinnigen Buchstaben am Ende\r\n
Jetzt könnte recv() das zum Beispiel so empfangen

Code: Alles auswählen

# Block 1
Hallo ich\r\nbin ein Bespiel\r\nText mit
# Block 2
unsinnigen Buchstaben am Ende\r\n

Verfasst: Samstag 2. Januar 2010, 13:46
von maxi_king_333
Hi,

schonmal Vielen Dank - ich habe wieder einiges dazu gelernt.
@maxi_king_333: Die Namen von *Klassen* sollten gross geschrieben werden. `Tkinter` ist doch keine Klasse, sondern ein Modul. Und bei dem `socket`-Beispiel binde ich nicht das Modul `socket` an den Namen `Socket`, sondern die Klasse `socket` *aus* diesem Modul. Interessanterweise heist die Klasse ursprünglich `_socketobject` und wird erst nachträglich an den Namen `socket` gebunden:
Man muss sich erstmal den Unterschied zwischen Funktionen und Modulen klar werden.
Ich denke ich habe es jetzt Verstanden.
Die Komplexität wird *jetzt* noch nicht gebraucht. Auf die Objekte in den Dictionaries wird nicht zugegriffen, also kann man sie auch weglassen.

Und ich versteh's immer noch nicht. Mir ist klar, dass man für verschiedene Ereignisse, die man Melden möchte, jeweils Objekte benötigt, die diese Verarbeiten, den Benutzer informieren, oder auch andere Aktionen auslösen. Aber warum muss man die in diese Dictionaries stecken? Warum mit Zufallszahlen als Schlüssel? Wie soll man da je wieder *gezielt* herankommen? Und wenn man das nicht kann, warum stecken die dann nicht einfach in Listen? Warum willst Du da später noch einmal drauf zugreifen? Gib doch mal bitte ein konkretes Beispiel.
Em also ich möchte da garnicht mehr drauf zugreifen, im Gegenteil - wenn die fertig gelaufen sind soll das Ding ja wieder gelöscht werden.
Darum geht es ja eigentlich - würde das mit Listen gehen - wobei ich muss höchstens 1 Mal drauf zugreifen nämlich wenn ich den Thread starte.
Also gut, ein Beispiel:
Der Nutzer hat folgende Konfiguration:
2 Telefone mit den Nummern 333 444.
Bei einem ausgehenden Anruf über 333: Notify (über Libnotify) "Ausgehender Anruf von 333 zu xxx"; Musik leiser; Wenn die Verbindung steht Musik aus
Bei einem ankommenden Anruf an 333: Notify (über Libnotify) "Ausgehender Anruf von xxx zu 333"; Musik leiser; Wenn die Verbindung steht Musik aus
Bei der Nummer 444 nichts tun.
Die Nummer 333 gehört ihm, die andere einem anderen Familien Mitglied.
Nun wird ein Anruf von 333 getätigt - Die Callmonitor Klasse empfängt das Signal.
Jetzt kommt Parse und wertet es aus - die Notifyer Klasse wird gestartet bzw. es wird ein neues Objekt von ihr erstellt.
Dieses *soll* nun die Konfiguration einlesen (Das macht sie jetzt noch nicht, also von mir aus schreiben wir es eben direkt in den Code) und daraus 3 Notify Objekte erzeugen.
Die Notify Objekte führen jetzt die Oben Genannten Dinge aus.
Und wenn der Anruf Ankommt passiert eben genau das gleiche.
Sollte irgendetwas mit der Nummer 444 an Notifer übergeben werden passiert nichts.
Nur um sicher zu gehen: Du weisst, dass die `Thread`-Objekte solange existieren, bis sie durchgelaufen sind? Auch wenn man keine Referenzen mehr darauf hält. Solange das Hauptprogramm läuft, braucht man sich da nicht mehr weiter zu kümmern. Für das Verhalten wenn das Hauptprogramm endet und noch Threads laufen, ist `Thread.setDaemon()` auf den jeweiligen `Thread`-Exemplaren. verantwortlich.
Ja, jetzt schon.
Aber es wird nicht alles als Thread gestartet - Die Notify Klasse gibt es 2 mal einmal ohne und einmal mit Thread - Wobei ich daraus heute Abend/Nacht ja eh Funktionen mache, die ich dann entweder als Thread oder eben nicht als Thread starte.
Die Frage mit der Klasse habe ich nicht verstanden!? Man kann in Klassen auf alle Namen zugreifen, die auf Modulebene bekannt sind.
Und wie heißt das Modul der Hauptdatei (fbcallnotify.py) - fbcallnotify?
Also theoretisch fbcallnotify.genrandomid()?
Das Problem mit `recv()` ist, dass die Gegenseite 'test\ntest1\n' nicht an einem Stück senden muss, sondern bei Dir auch bei einem `recv()`-Aufruf 'test\nte' und beim nächsten dann erst 'st1\n' ankommen kann. Es ist nicht wirklich garantiert, dass die Zeilen immer an einem Stück ankommen.

Das mit dem `dict()` in `parse.run()` hat einmal den Vorteil, dass `run()` nicht so gross wird und zum zweiten kann man es dann leichter erweitern. Das ist ausserdem die "pythonische" Art eine ``switch``-Anweisung auszudrücken, die es in anderen Programmiersprachen gibt. Ich würde an der Stelle wohl einen dynamischen "dispatch" anhand von ``info[1]`` machen, sofern man davon ausgehen kann, dass für die Fälle, die man behandeln möchte, immer etwas steht, was als Suffix eines gültigen Namens in Python durchgeht. Ungetestet: http://paste.pocoo.org/show/161268/
Asch so ist das gemeint - dann bau ich eine Schleife ein, die wartet bis nichts mehr kommt.

Viele Grüße
Maxi

Verfasst: Samstag 2. Januar 2010, 13:57
von Dav1d
Man muss sich erstmal den Unterschied zwischen Funktionen und Modulen klar werden.
Ich denke ich habe es jetzt Verstanden.
Eher den Unterschied zwischen Modulen, Klassen und Funktionen
Asch so ist das gemeint - dann bau ich eine Schleife ein, die wartet bis nichts mehr kommt.
Du könntest den Datenblock spllitten z.B. bei '\n', dann jede Zeile prüfen ob sie auf '\r' endet, wenn nicht die Zeile "speichern" und dann mit der 1. Zeile des nächsten Datenblocks zusammen führen, wenn der Delimiter \n ist, musst du dir was anderes überlegen oder ein data.replace('\n', '\r\n') machen

Verfasst: Samstag 2. Januar 2010, 14:05
von maxi_king_333
Du könntest den Datenblock spllitten z.B. bei '\n', dann jede Zeile prüfen ob sie auf '\r' endet, wenn nicht die Zeile "speichern" und dann mit der 1. Zeile des nächsten Datenblocks zusammen führen, wenn der Delimiter \n ist, musst du dir was anderes überlegen oder ein data.replace('\n', '\r\n') machen
Da das alles von einem Linux gesendet wird gibt es nun mal nur ein \n.
Oder mischt da Python noch mit?
Kann ich das nicht durch eine Schleife Lösen?

Code: Alles auswählen

infostr = ""
tmpinfo = self.recv(8192)
while tmpinfo != "":
    infostr += tmpinfo
    tmpinfo = self.recv(8192)

Verfasst: Samstag 2. Januar 2010, 14:09
von Dav1d
Diese Schleife würde existieren bis die Verbindung beendet wird.

Code: Alles auswählen

buf = ''
while True:
    data = s.recv(2**14)
    if data:
        data = buf + data
        foo = False
        if data.endswith('\n'):
            foo = True
        splitted_data = data.splitlines()
        if not foo:
            buf = splitted_data.pop()
    else:
        break
wäre auch eine Möglichkeit

Code erweitert

Verfasst: Sonntag 3. Januar 2010, 11:30
von maxi_king_333
Hi,

also Vielen Dank für Eure Hilfe.
Ich habe einiges umgeschrieben und mir ist aufgefallen, dass ich so manche Klasse lieber durch ein Modul ersetzen sollte.
Nun hoffe ich, dass Ihr Zeit dafür habt noch einmal einen Blick drüber zu werfen und zu schauen ob nun alles gut ist.
In der Parse Klasse habe ich die Events noch nicht in ein Dict verbaut, aber dafür mein neues Wissen gleich bei dem Modul notifyer angewendet.
Dort sind die Events in einem Dict verzeichnet.
Ein Problem habe ich dort allerdings noch - event_libnotify() funktioniert nicht.
Also ich bekomme keine Fehlermeldung oder so - es wird einfach nur kein Notify Ballon angezeigt.

Viele Grüße und nochmal Danke an Alle
Maxi

Verfasst: Montag 4. Januar 2010, 10:06
von maxi_king_333
Hi,

libnotify funktioniert jetzt - ich habe erst noch libnotify-dev installieren müssen.
Kann ich das irgendwie umgehen, also so, dass man nicht extra die dev Pakete installieren muss?

Viele Grüße
Maxi

Verfasst: Montag 4. Januar 2010, 13:15
von Leonidas
maxi_king_333 hat geschrieben:Kann ich das irgendwie umgehen, also so, dass man nicht extra die dev Pakete installieren muss?
Also nachdem man die Libraries kompiliert hat, benötigt man die -dev-Pakete eigentlich nicht mehr.

Verfasst: Montag 4. Januar 2010, 13:17
von maxi_king_333
Hi,
Also nachdem man die Libraries kompiliert hat, benötigt man die -dev-Pakete eigentlich nicht mehr.
OK, Vielen Dank, war bestimmt irgendein anderer andere Fehler von mir .

Viele Grüße
Maxi