Klassenfelder auslesen?

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
capgeti
User
Beiträge: 9
Registriert: Donnerstag 9. September 2010, 11:39

Hallo.

Ich hab eine Klasse und instanziere diese:

Code: Alles auswählen

class Test:
    def __init__(self, x, y, state1, state2):
        self.x = x
        self.y = y
        self.state1 = state1
        self.state2 = state2

testInstance = Test(2, 2, True, False)
print(testInstace.x)
Gibt es eine Möglichkeit in Python alle Felder der klasse auszulesen?
also:

Code: Alles auswählen

for field in testInstance.getFields():  #testInstance.getFields() returns ("x", "y", "state1", "state2")
    print(field)
Ich hoffe ihr könnt mir helfen!

lg Michael
Benutzeravatar
cofi
Python-Forum Veteran
Beiträge: 4432
Registriert: Sonntag 30. März 2008, 04:16
Wohnort: RGFybXN0YWR0

Ja, allerdings ist es besser eine eigene Methode zu schreiben, um dem hier vorzubeugen:

Code: Alles auswählen

>>> t = Test(1,2,3,4)
>>> t.__dict__
{'y': 2, 'x': 1, 'state1': 3, 'state2': 4}
>>> t._this_should_not_be_exposed = "secret"
>>> t.__dict__
{'y': 2, 'x': 1, 'state1': 3, '_this_should_not_be_exposed': 'secret', 'state2': 4}
capgeti
User
Beiträge: 9
Registriert: Donnerstag 9. September 2010, 11:39

oO
wow cool... Ist ja einfach.
Hast aber recht. Sieht net wirklich toll aus.

danke =)
EyDu
User
Beiträge: 4881
Registriert: Donnerstag 20. Juli 2006, 23:06
Wohnort: Berlin

Hallo.

Wenn du verrätst, was du eigentlich vor hast, dann findet sich vielleicht eine elegantere Lösung. Unter Umständen könntest du direkt ein Dictionary verweden.

Bis dann,
Sebastian
Das Leben ist wie ein Tennisball.
capgeti
User
Beiträge: 9
Registriert: Donnerstag 9. September 2010, 11:39

Also ich versuche für mein Spiel ein Netzwerkmodul zu schreiben.

Damit man nicht sich jedes mal kümmern muss, an welcher stelle in einem tuple die pos x steht, hatte ich die idee eine art PresentationClass für übertragungen anzulegen.
zb. Client:

Code: Alles auswählen

client.send(PositionUpdate(player))
Server:

Code: Alles auswählen

# Bei init,
# registriert funktion onPosUpdate im Server und ruft diese auf, falls ein PositionUpdate "event" kommt
server.register(onPosUpdate, PositionUpdate)

def onPosUpdate(client, data):
    # data ist eine PositionUpdate instanz
    print( client.address, data.x )
Presentations:

Code: Alles auswählen

class PositionUpdate:
    def __init__(self, player):
        self.x = player.x
        self.y = player.y

Wenn ich auf Clientseite die Daten schicken will, hab ich bis jetzt mit pickle einen geeigneten string der klasse PositionUpdate erstellt.
Da aber noch zu viel "müll" drin ist, wollte ich selbst ein "transfer-string" zusamemstellen und ihn auf server seite wieder umwandeln.

Natürlich könnt ich auch einfach dicts nehmen, aber die IDE unterstützt code completion, was bei nem dict nicht viel nützt, bei einer klasse aber schon.

ich hoffe ich habs verständlich erklärt ^^, falls nicht, fragt einfach.

lg
Benutzeravatar
Hyperion
Moderator
Beiträge: 7478
Registriert: Freitag 4. August 2006, 14:56
Wohnort: Hamburg
Kontaktdaten:

Wenn pickle zu viel "Müll" mitliefert, probiere doch mal jsonrpc oder xmlrpc aus. Ist halt weniger low-level und Du bestimmst selber die exakten Parameter, die übertragen werden.
encoding_kapiert = all(verstehen(lesen(info)) for info in (Leonidas Folien, Blog, Folien & Text inkl. Python3, utf-8 everywhere))
assert encoding_kapiert
capgeti
User
Beiträge: 9
Registriert: Donnerstag 9. September 2010, 11:39

JSON kam mir auch schon in den Sinn, ist aber noch zu viel müll drin.

Code: Alles auswählen

{"jsonrpc": "2.0", "method": "update", "params": {"x": 23, "y": 42}, "id": 3}
Ich will aber sowas:

Code: Alles auswählen

(3, 23, 42)
das spart an traffic.
Wobei 3 die id ist, 23 ist x und 42 ist y.
Dieses Tubel erzeugt der Client, indem er alle felder der klasse durchgeht und die werte reinschreibt.
Der erste wert ist die id der klasse.
Ich müsste jetzt nur noch global definieren, das id 3 die PositionsUpdateKlasse ist,
dann auf serverseite eine instanz davon erzeugen und den rest des tubels als para für den kontruktor...

so müsste das doch auch gehen oder ni?
Benutzeravatar
Hyperion
Moderator
Beiträge: 7478
Registriert: Freitag 4. August 2006, 14:56
Wohnort: Hamburg
Kontaktdaten:

capgeti hat geschrieben: so müsste das doch auch gehen oder ni?
Die Frage ist, ob es sich lohnt so viel "Optimierung" zu betreiben und dafür ein kryptisches, scher zu debuggendes Protokoll zu erhalten? Der JSON-String oben enthält zwar mehr Bytes, aber passt vermutlich immer noch in ein TCP-Paket ;-) Bei Spielen ist eher die Latenz das Hauptproblem, nicht die Datenmenge.

Ok, ich weiß jetzt nicht, wieviele Bytes Du da übertragen musst, aber dennoch würde ich erst einmal auf Lesbarkeit, Wartbarkeit und höhere Module setzen, anstatt so früh an einer Lösung zu "frickeln".

Alternativ gibts ja auch noch diese google-Dingens...
http://code.google.com/intl/de-DE/apis/protocolbuffers/
encoding_kapiert = all(verstehen(lesen(info)) for info in (Leonidas Folien, Blog, Folien & Text inkl. Python3, utf-8 everywhere))
assert encoding_kapiert
DasIch
User
Beiträge: 2718
Registriert: Montag 19. Mai 2008, 04:21
Wohnort: Berlin

capgeti hat geschrieben:Ich will aber sowas:

Code: Alles auswählen

(3, 23, 42)
Du könntest dir was mit ast.literal_eval, repr und ZeroMQ basteln.
Benutzeravatar
Hyperion
Moderator
Beiträge: 7478
Registriert: Freitag 4. August 2006, 14:56
Wohnort: Hamburg
Kontaktdaten:

DasIch hat geschrieben:
capgeti hat geschrieben:Ich will aber sowas:

Code: Alles auswählen

(3, 23, 42)
Du könntest dir was mit ast.literal_eval, repr und ZeroMQ basteln.
Nichts für ungut, aber das Wort "basteln" spricht da wohl Bände :mrgreen:
encoding_kapiert = all(verstehen(lesen(info)) for info in (Leonidas Folien, Blog, Folien & Text inkl. Python3, utf-8 everywhere))
assert encoding_kapiert
capgeti
User
Beiträge: 9
Registriert: Donnerstag 9. September 2010, 11:39

@Hyperion
Sieht sehr schön aus von der Datenmenge und der benutzung her.
Naja, bis auf das man kleine "templates" für seine message types anlegen muss, damit man die in python verwenden kann -.-
mhm... vllt kann man diesen schritt noch automatisieren.

Aber ansonsten ist es sehr schön.
Leonidas
Python-Forum Veteran
Beiträge: 16025
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

capgeti hat geschrieben:Ich will aber sowas:

Code: Alles auswählen

(3, 23, 42)
das spart an traffic.
Naja, ist halt die Frage ob es nicht reicht das in gzip (oder zur not auch LZO) zu packen.
My god, it's full of CARs! | Leonidasvoice vs (former) Modvoice
Antworten