Seite 1 von 1
Mal wieder Dictionairies
Verfasst: Sonntag 13. August 2006, 20:48
von murph
Code: Alles auswählen
cv2 = {}
class Client:
class LoginError(Exception):
def __init__(self):
sys.stdout.write('\n')
pass
class ServerError(Exception):
pass
class SqliteOperationalError(Exception):
pass
def connect(self,**kwargs):
socket.setdefaulttimeout(client_vardic['sockettimeout'])
cv2['user'] = kwargs['user']
cv2['rcv_addr'] = (client_vardic['host'],client_vardic['rcv_port'])
cv2['send_addr'] = (kwargs['server'],client_vardic['send_port'])
cv2['TCPSocksend'] = socket.socket(socket.AF_INET,socket.SOCK_DGRAM)
cv2['TCPSockrcv'] = socket.socket(socket.AF_INET,socket.SOCK_DGRAM)
cv2['TCPSockrcv'].bind(cv2['rcv_addr'])
cv2['crypt_pw'] = sha.new(kwargs['passwd']).hexdigest()
if 'cryptmaterial' in kwargs:
todo = ['login',cv2['user'],cv2['crypt_pw'], 'crypt_true']
cv2['TCPSocksend'].sendto(cPickle.dumps(todo),cv2['send_addr'])
cv2['TCPSocksend'].sendto(kwargs['cryptmaterial'],cv2['send_addr'])
else:
todo = ['login',cv2['user'],cv2['crypt_pw'], 'crypt_false']
cv2['TCPSocksend'].sendto(cPickle.dumps(todo),cv2['send_addr'])
recieved = cPickle.loads(cv2['TCPSockrcv'].recvfrom(1024)[0])
if not recieved[0]:
raise self.LoginError(recieved[1])
cv2['sid'] = recieved[1]
return self.CursorDummy()
def change_pw(self,old_pw, new_pw):
#[...]
def reset_client(self,pw):
#[...]
def crypt_my_database(self, rubbish, pw):
#[...]
class CursorDummy:
def __init__(self):
self.shutdown = False
class cursor:
class SqliteOperationalError(Exception):
pass
class RowCount(object):
def read_bar(self):
todo = [cv2['sid'], 'rowcount', 'varget']
cv2['TCPSocksend'].sendto(cPickle.dumps(todo),cv2['send_addr'])
self._bar = cPickle.loads(cv2['TCPSockrcv'].recvfrom(1024)[0])
return self._bar
bar = property(read_bar)
def __init__(self):
self.read_bar()
rowcount = RowCount()
def setinputsizes(self, sizes):
todo = [cv2['sid'], 'setinputsizes', sizes]
cv2['TCPSocksend'].sendto(cPickle.dumps(todo),cv2['send_addr'])
cv2['TCPSockrcv'].recvfrom(1024)
mein problem ist, dass ich nur an einer einzigen stelle auf cv2 NICHT zugreifen kann.
nur die klasse RowCount kann ich nicht initialisieren lassen!
erst, wenn ich "per hand" sie starte, funktioniert sie.
um da genauer auszuführen:
wenn ich die methode test einführe, die RowCount initialisiert, ist das kein Problem.
Wenn ich aber einer anderen Variable den wert zuweise, kommt ein keyerror:
Traceback (most recent call last):
File "sqliteserver.py", line 465, in ?
class Client:
File "sqliteserver.py", line 527, in Client
class CursorDummy:
File "sqliteserver.py", line 530, in CursorDummy
class cursor:
File "sqliteserver.py", line 543, in cursor
rowcount = RowCount().bar
File "sqliteserver.py", line 541, in __init__
self.read_bar()
File "sqliteserver.py", line 535, in read_bar
todo = [cv2['sid'], 'rowcount', 'varget']
KeyError: 'sid'
Verfasst: Montag 14. August 2006, 08:09
von BlackJack
Du erwartest tatsächlich das jemand versucht durch diesen verschachtelten Klassen-Murks durchzusteigen!?
Bitte arbeite Dich noch einmal durch ein Anfängertutorial durch. Da sind so viele "Grausamkeiten" in Deinem Quelltext das man gar nicht weiss wo man anfangen soll.
Zum verschachteln gibt's was im Python-Zen:
Simple is better than complex. [...]
Flat is better than nested. [...]
Readability counts.
Verfasst: Montag 14. August 2006, 10:44
von murph
@ blackjack:
tutorials habe ich leider schon gemacht, kann aber schlecht davon lernen.
ich sehe selbst kein Problem in der Konstruntion, muss aber auch nicht durchsteigen^^
ich kann folglich schlecht nahcvollziehen, wo das leseproblem ist,
da es für mich sehr einfach zu lesen und zu verstehen ist.
der script funktioniert unter dem gesichtspunkt, das ich die konstruktion aufgegen habe und die variable mir von einer methode von cursor ausgeben lasse.
Verfasst: Montag 14. August 2006, 11:42
von CM
Hi murph,
BlackJack hat schon recht, wenn die Worte auch etwas harsch sind

: Nein, Du wirst, wenn das Projekt erst ein wenig größer ist es so nicht mehr einfach lesen und verstehenn können und irgendwann auch gar nicht mehr durchsteigen. Das können wir Dir jetzt schon sagen.
Mal ganz grob eine Struktur, wie Du sie beherzigen solltest:
Code: Alles auswählen
class MyFirstError(Exception):
"""Exception helper class for defining and tuning Exceptions
- for internal use, only"""
def __init__(self,value):
self.value = value
def __str__(self):
return repr(self.value)
class MySecondError(MyFirstError): pass
#und analog dazu weitere Fehlerklassen
#dann:
class MyFunctionalityClass():
def __init__(self,*args):
#bla bla
def function1(self,*args):
#bla bla
Vielleicht lösen sich auch einige der Probleme mit etwas mehr Struktur im Code in Wohlgefallen auf.
Gruß,
Christian
Verfasst: Montag 14. August 2006, 13:04
von keppla
ich sehe selbst kein Problem in der Konstruntion, muss aber auch nicht durchsteigen^^
auch wenn du kein Problem siehst, der Kompiler tut das ganz offensichtlich.
deshalb: doch, du SOLLTEST durchsteigen, immerhin enthält das obige konstrukt mindestens einen fehler, den du weder finden, noch auf einen kleinen bereich (60+ Zeilen sind nicht klein) einschränken kannst.
Warum tust du Klassen in Klassen in Klassen? Welcher genaue Vorteil (nein, "ich finde das cool" ist kein Vorteil) wird dadurch erreicht? Wenn du Module möchtest, dann nutze doch die, anstatt Klassen zu missbrauchen
Verfasst: Montag 14. August 2006, 13:50
von KC25m
rowcount = RowCount() , wird schon aufgerufen bevor du überhaupt was in cv2 hast.
Dein Dict is zu diesen zeitpunkt leerer als leer ...
Daher schreib dir eine Funktion die dann erstmal deine zeile aufruf.
Ansonsten wirste noch baden gehen

Verfasst: Montag 14. August 2006, 15:30
von murph
wieso ist das dictionairy leer?
zu dem zeitpunkt des aufrufens der klasse ist das dictionairy doch ziemlich voll.
der fehler ist allerdings ziemlich genau, ich wollte nur den fragen vorbeugen, ob es das dictionairy gibt, ob es global ist etc etc etc
Verfasst: Montag 14. August 2006, 16:33
von KC25m
Also sobald dein Interpreter an der classe vorbeirennt interpretiert er alles was auserhalb der funktionen steht
Code: Alles auswählen
class MainClass:
class SubClass:
def __init__(self):
INIT=True
class SubClassOfSubClass:
def __init__(self):
print "Jetzt bin ich Dran"
print "Ich werde schon ohne expliziten Aufruf gestartet !"
dadurch wird dein aufruf schon nach dem laden der Classe aufgerufen und da ist das Dict noch nicht voll , da du es oben ja erst anlegst.
cv2={}
pack den aufruf einfach in eine Funktion die du dan aufrufst schon solte es gehen.
Das dict gibt es zu dem zeitpunk noch nicht nur das leere Arraye cv2={}
Verfasst: Dienstag 15. August 2006, 10:59
von murph
aso. da muss ich ja einen ganz neuen weg gehen, aber thx für ausführung!
Verfasst: Dienstag 15. August 2006, 13:00
von KC25m
solte schon reichen damit dein befehlt nicht ausgeführt wird ohne das was im Dict ist .
if cv2 guckt nicht ob es existiert sondern ob was drin ist , da beim ersten durchlauf nichts drin ist übergeht es die nachfolgenden befehle.
[/quote]
Verfasst: Dienstag 15. August 2006, 14:01
von Michael Schneider
Einspruch!
Sobald man eine solche Wahrheitsprüfung auf ein Objekt durchführt, wird die interne Funktion __nonzero__ aufgerufen. Wenn das Objekt nicht im aktuellen (zumindest globalen) Namensraum existiert, gibt's 'nen NameError.
Übrigens: es gibt auch Wege, sicher auf ein Dictionary zuzugreifen. Machen das Programm fehlertoleranter (auch wenn sie manchmal das Debuggen erschweren).
Code: Alles auswählen
>>> d = {"Hallo":1, "Welt":2}
>>> d.has_key("Hallo")
1
>>> d.has_key("World")
0
>>> d.get("Hallo", "nicht vorhanden (default)")
1
>>> d.get("World", "nicht vorhanden (default)")
'nicht vorhanden (default)'
Grüße,
der Michel
Verfasst: Mittwoch 16. August 2006, 09:21
von keppla
das klingt für mich nicht nach fehlertoleranter, sondern eher nach
except: pass
Wenn ich davon ausgehe, dass ein bestimmter Schlüssel mit einem Wert assoziiert sein muss, und es nicht der Fall ist, so ist das ein Fehler, der auch als solcher eine Exception verursachen sollte, damit ich ihn finden kann. Und üblicherweise verhindert eine solche "ignorieren, weitermachen"-maßnahme keine fehler, sie verschiebt sie nur an unerklärbarere Stellen, wie du schon andeutest.
In diesem Sinne: dies hier ist nicht das PHP-Forum

Verfasst: Mittwoch 16. August 2006, 09:54
von birkenfeld
sollte man nicht mehr verwenden.
ist schneller und schöner.
Verfasst: Mittwoch 16. August 2006, 14:05
von Michael Schneider
Hi Keppla,
ich kann Dir nicht ganz zustimmen.
keppla hat geschrieben:das klingt für mich nicht nach fehlertoleranter, sondern eher nach
except: pass
Wohl eher nach except:
return alternative
keppla hat geschrieben:Wenn ich davon ausgehe, dass ein bestimmter Schlüssel mit einem Wert assoziiert sein muss, und es nicht der Fall ist, so ist das ein Fehler, der auch als solcher eine Exception verursachen sollte, damit ich ihn finden kann.
Wenn das Dictionary existiert und Du den Inhalt kennst, magst Du recht haben. Wenn man ein Dictionary aufbaut ist das aber häufig nicht so. Z.B. wenn man eine unbekannte Menge auswertet kann dict.get ganz praktisch sein:
Code: Alles auswählen
from random import randint
lInput = [randint(1,20) for i in range(10)]
dRes = {}
for i in lInput: dRes[i] = dRes.get(i, 0) + 1
print dRes
Du hast genau das angesprochen, was auch ich schon andeutete. WENN man bestimmte Schlüssel erwartet, dann sollte widrigenfalls auch eine Exception geworfen werden.
Grüße,
der Michel
Verfasst: Mittwoch 16. August 2006, 14:38
von keppla
Wenn das Dictionary existiert und Du den Inhalt kennst, magst Du recht haben.
Das war doch der fall, oder vertue ich mich da? Murph fragte sich, warum ein schlüssel fehlte, der da sein müsse.
Wenn man ein Dictionary aufbaut ist das aber häufig nicht so. Z.B. wenn man eine unbekannte Menge auswertet kann dict.get ganz praktisch sein:
Klar, da stimme ich zu. Nur klang das ganze eben etwas nach except: pass, weil du "Fehlertoleranter" sagtest, und von einem erschwerten debugging redetest. Entweder hat man die Zusicherung, dass werte vorhanden sind, dann darf man imho kein default verwenden, oder man hat sie nicht, dann muss man (wie auch immer die implementierung aussieht) eine art default verwenden. Nur gibt es da keinen Übergang: fall a wird nicht besser durch ein default, und fall b ist nicht vollständig ohne.
Deshalb mein Missverständniss
Verfasst: Mittwoch 16. August 2006, 17:12
von Michael Schneider
Hi keppla!
keppla hat geschrieben:Wenn das Dictionary existiert und Du den Inhalt kennst, magst Du recht haben.
Das war doch der fall, oder vertue ich mich da? Murph fragte sich, warum ein schlüssel fehlte, der da sein müsse.
Richtig. Ich drücke mich manchmal (offenbar zu häufig) unklar aus. Der Teil nach dem "Übrigens:" sollte eigentlich allgemeinen Charakter haben und sich nicht mehr auf das Beispiel beziehen! Wenn ich das nochmal lese muss ich zugeben, dass diese Andeutung nicht so gut rüberkam. Sorry.
Und "fehlertoleranter" ist noch so ein unglückliches (eigentlich falsches) Wort, an dieser Stelle. Wollte sagen, dass man damit "sicher" das Vorkommen eines Wertes feststellen kann, um so beispielsweise einen initialen Schleifendurchlauf von den Weiteren zu trennen.
Missverständnisse habe also ich verursacht. Ich werde versuchen, meine Gedanken präziser zu formulieren.
Grüße,
der Michel