Seite 1 von 1

"New-Style"-Classes und Deskriptoren

Verfasst: Montag 12. Januar 2009, 18:02
von bwbg
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

Verfasst: Sonntag 18. Januar 2009, 19:22
von str1442
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.

Verfasst: Montag 19. Januar 2009, 22:15
von bwbg
(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.