Seite 1 von 1

Property zur Laufzeit generieren

Verfasst: Mittwoch 26. März 2008, 14:05
von moesibaer
Hallo,

ich möchte in meiner Klasse die Property Objekte zur Laufzeit generieren. Hier der aktuelle Code, der eine übergebenes SQLObjekt durchläuft und aus seinen properties die meiner Klasse macht. Diese will ich dann teilweise in meiner Klasse überschreiben um bei den Settern einige Überprüfungen durchzuführen, bevor der Wert in die Datenbank kommt. Die anderen sollen durch die lambda Funktion gesperrt werden.

Code: Alles auswählen


def GetSetterName(name):
    return "_set_%s" % name
def GetGetterName(name):
    return "_get_%s" % name
def GetPropertyName(name):
    return name

class MyObjekt(object):
_obj = None #speichert das Resultat von get
_table = None
_name = None

def __init__(self,table,name):    
        self._table = table
        self._name = name

       #sqlobject durchlaufen
        for name,item in table.__dict__.iteritems():
            #fuer jedes property im sqlobject
            #ein eigenes in dieser klasse schalten
            if isinstance(item,property):
                getter = lambda self,value: eval("self._obj.%s" % name)
                setter = lambda self,value: False #Standard soll sein, den Setter fuer das SQLOBjekt zu verbieten, wo es erlaubt ist soll das property ueberschrieben werden
                setattr(self, GetSetterName(name), setter)
                setattr(self, GetGetterName(name), getter)
                setattr(self, GetPropertyName(name), property(setter,getter))

class User(MyObject):
    def __init__(self):
        super(User, self).__init__(UserTable,"User")

Problem ist nun das ich folgende Ausgabe bekomme

Code: Alles auswählen

>>>a = User()
>>>a.get(1) #holt sich aus der Tabelle die spalte mit der ID 1, ist nicht im Code oben drin
>>>a.name
<property object at 0x833ad4c>
In wie weit geh ich das falsch an?

Danke für jede Hilfe!

Verfasst: Mittwoch 26. März 2008, 14:24
von Trundle
Propertys werden Deskriptoren sein, und die müssen im Klassendictionary sein und nicht im Dictionary vom Klassenexemplar (siehe Referenz). Du müsstest also jedes Mal eine neue Klasse mit den jeweiligen Propertys erstellen und davon ein Exemplar erstellen.

Verfasst: Mittwoch 26. März 2008, 14:31
von audax
Überschreib einfach __getattr__ und __setattr__, du machst dir das zu kompliziert.

Ich bau grad nen Beispiel

Verfasst: Mittwoch 26. März 2008, 14:56
von audax

Code: Alles auswählen

class Foobar(object):

    def _locked(self, *args):
        raise AttributeError, "Property is locked"

    def __getattr__(self, value):
        return object.__getattribute__(self, "get_%s" % value).__call__(self)

    def __setattr__(self, value, item):
        return object.__getattribute__(self, "set_%s" % value).__call__(self, item)

    def lock(self, value):
        func = getattr(self, "set_%s" % value)
        if func != self._locked:
            object.__setattr__(self, "_set_%s" % value, func)
            object.__setattr__(self, "set_%s" % value, self._locked)
        else:
            object.__setattr__(self, "set_%s" % value,
                object.__getattribute__(self, "_set_%s" % value))

    def init(self, value):
        object.__setattr__(self, "get_%s" % value,
            lambda self, : object.__getattribute__(self, value))
        object.__setattr__(self, "set_%s" % value,
            lambda self, item: object.__setattr__(self, value, item))

if __name__ == "__main__":
    foo = Foobar()
    foo.init("bar")
    foo.bar = "baz"
    print foo.bar
    foo.lock("bar")
    try:
       foo.bar = "foobar"
    except AttributeError, e:
        print e
    print foo.set_bar
    foo.lock("bar")
    print foo.set_bar
    print foo._set_bar
    foo.bar = "bubu"
    print foo.bar

Code: Alles auswählen

baz
Property is locked
<bound method Foobar._locked of <__main__.Foobar object at 0x4032772c>>
<function <lambda> at 0x40319224>
<function <lambda> at 0x40319224>
bubu

Verfasst: Mittwoch 26. März 2008, 15:06
von moesibaer
ah korrekt, herzlichen Dank, das ist ne Gute Sache! Vielen Dank für das Beispiel!