"New-Style"-Classes und Deskriptoren

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
Benutzeravatar
bwbg
User
Beiträge: 407
Registriert: Mittwoch 23. Januar 2008, 13:35

Hallo zusammen,

ich habe in zusammenhang mit den New-Style-Classes von Deskriptoren gelesen und mir versucht, ein greifbares Beispiel zu generieren.

Sogesehen wollte ich in diesem exemplarischen Beispiel einen Datentypen generieren, welcher bei einem "Überlauf" wieder von 0 an zählt.

Spielereien, wie eine Nachricht an ein anderes Attribut habe ich jetzt mal außen vor gelassen.

Code: Alles auswählen

#!/usr/bin/env python
# -*- coding: utf-8 -*-

def mask(name, bits):
    return '__reg%d_%s' % (bits, name)

class Register(object):
    def __init__(self, name, bits=8):
        self.name = name
        self.bits = bits
    
    def __get__(self, _object, _type):
        if _object and _object.__dict__.has_key(mask(self.name, self.bits)):
            return _object.__dict__[mask(self.name, self.bits)]
        else:
            return None
    
    def __set__(self, _object, value):
        if _object:
            _object.__dict__[mask(self.name, self.bits)] = value % (2 ** self.bits)
 
class CPU(object):
    accu = Register(name='accu')
    ip = Register(name='ip', bits=16)
    
c0 = CPU()
c0.accu = 145
print c0.accu

c0.accu = 257
print c0.accu

c1 = CPU()
c1.accu = 56
print c1.accu != c0.accu

print dir(c0)
Da die ganze Thematik doch sehr Abstrakt ist, stelle ich die Frage in den Raum, ob ich das Konzept so richtig aufgefasst habe, oder ob der Sinn dieser Konstruktion ein ganz anderer ist.

Grüße... Heiko
Benutzeravatar
str1442
User
Beiträge: 520
Registriert: Samstag 31. Mai 2008, 21:13

Deskriptoren kann man durchaus für sowas einsetzen, auch wenn dein Code sehr magic aussieht. Für geläufige Anwendungen sind Deskriptoren aber eher der Stahlhammer auf der Wallnuß. Für deine Aufgabe gibt es Properties:

Code: Alles auswählen

In [1]: class CPU(object):
   ...:     def __init__(self):
   ...:         self._accu = 0
   ...:     def _set_accu(self, other):
   ...:         self._accu = other if other < 256 else other % 256
   ...:     accu = property(lambda self: self._accu, _set_accu)
   ...:     
   ...:     

In [2]: a = CPU()

In [3]: print a.accu
0

In [4]: a.accu = 100

In [5]: print a.accu
100

In [6]: a.accu = 280

In [7]: print a.accu
24

In [8]: 280 % 256
Out[8]: 24
Ich wüsste keine wirklich sinnvolle Anwendung für Deskriptoren (obwohl ich meine, das Python Interna sie verwenden) in richtigem Code.
Benutzeravatar
bwbg
User
Beiträge: 407
Registriert: Mittwoch 23. Januar 2008, 13:35

(Ein Wunder, dass überhaupt jemand an mein Topic gedacht hat ... :wink: )

An die Properties habe ich anhand meines Beispieles auch schon gedacht. Mir stieß aber sauer auf, dass es doppelten Code durch die setter-Methoden bedeutete. In diesem Beispiel ist es trivial, erhöhte man die Zahl der "Register" oder erhöhte man deren Komplexität (Verknüpfungen zwischen diesen, logging, etc.) würde das Ganze m.E. recht schnell unübersichtlich.
Antworten