Mal wieder Dictionairies

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
murph
User
Beiträge: 622
Registriert: Freitag 14. April 2006, 19:23
Kontaktdaten:

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'
http://www.cs.unm.edu/~dlchao/flake/doom/
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.
murph
User
Beiträge: 622
Registriert: Freitag 14. April 2006, 19:23
Kontaktdaten:

@ 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.
http://www.cs.unm.edu/~dlchao/flake/doom/
CM
User
Beiträge: 2464
Registriert: Sonntag 29. August 2004, 19:47
Kontaktdaten:

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
Benutzeravatar
keppla
User
Beiträge: 483
Registriert: Montag 31. Oktober 2005, 00:12

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
KC25m
User
Beiträge: 65
Registriert: Freitag 14. Juli 2006, 12:11
Wohnort: Kassel
Kontaktdaten:

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 :P
murph
User
Beiträge: 622
Registriert: Freitag 14. April 2006, 19:23
Kontaktdaten:

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
http://www.cs.unm.edu/~dlchao/flake/doom/
KC25m
User
Beiträge: 65
Registriert: Freitag 14. Juli 2006, 12:11
Wohnort: Kassel
Kontaktdaten:

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={}
murph
User
Beiträge: 622
Registriert: Freitag 14. April 2006, 19:23
Kontaktdaten:

aso. da muss ich ja einen ganz neuen weg gehen, aber thx für ausführung!
http://www.cs.unm.edu/~dlchao/flake/doom/
KC25m
User
Beiträge: 65
Registriert: Freitag 14. Juli 2006, 12:11
Wohnort: Kassel
Kontaktdaten:

Code: Alles auswählen

if cv2:
        rowcount = RowCount() 
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]
Benutzeravatar
Michael Schneider
User
Beiträge: 569
Registriert: Samstag 8. April 2006, 12:31
Wohnort: Brandenburg

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
Diese Nachricht zersört sich in 5 Sekunden selbst ...
Benutzeravatar
keppla
User
Beiträge: 483
Registriert: Montag 31. Oktober 2005, 00:12

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 ;)
Benutzeravatar
birkenfeld
Python-Forum Veteran
Beiträge: 1603
Registriert: Montag 20. März 2006, 15:29
Wohnort: Die aufstrebende Universitätsstadt bei München

Code: Alles auswählen

dict.has_key(key)
sollte man nicht mehr verwenden.

Code: Alles auswählen

key in dict
ist schneller und schöner.
Benutzeravatar
Michael Schneider
User
Beiträge: 569
Registriert: Samstag 8. April 2006, 12:31
Wohnort: Brandenburg

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
Diese Nachricht zersört sich in 5 Sekunden selbst ...
Benutzeravatar
keppla
User
Beiträge: 483
Registriert: Montag 31. Oktober 2005, 00:12

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
Benutzeravatar
Michael Schneider
User
Beiträge: 569
Registriert: Samstag 8. April 2006, 12:31
Wohnort: Brandenburg

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
Diese Nachricht zersört sich in 5 Sekunden selbst ...
Antworten