Angenommen, ich habe eine Klasse, und ich möchte viele ähnliche "Eigenschaften" -Attribute erstellen. Zum Beispiel:Sollte ich eine Deskriptorklasse oder eine Eigenschaftenfabrik verwenden?
class Foo(object):
@property
def foo(self):
return self._foo
@foo.setter
def foo(self, val):
self.update()
self._foo = val
@property
def bar(self):
return self._bar
@bar.setter
def bar(self, val):
self.update()
self._bar = val
@property
def baz(self):
return self._baz
@baz.setter
def baz(self, val):
self.update()
self._baz = val
def update(self):
print "Updating..."
Offensichtlich gibt es hier eine Menge Wiederholungen, und es wäre nett, dies zu berücksichtigen. Eine Möglichkeit wäre, um eine Funktion zu machen, die eine Eigenschaft gibt:
def create_property(var):
def _setter(self, val):
self.update()
setattr(self, '_' + var, val)
def _getter(self):
return getattr(self, '_' + var)
return property(_getter, _setter)
class Foo(object):
foo = create_property("foo")
bar = create_property("bar")
baz = create_property("baz")
def update(self):
print "Updating..."
Alternativ könnte ich einen Descriptor-Klasse schreiben:
class UpdateOnChange(object):
def __init__(self):
self.data = WeakKeyDictionary()
def __get__(self, instance, owner):
try:
return self.data[instance]
except KeyError:
raise AttributeError("attribute not set")
def __set__(self, instance, value):
instance.update()
self.data[instance] = value
class Foo(object):
foo = UpdateOnChange()
bar = UpdateOnChange()
baz = UpdateOnChange()
def update(self):
print "Updating"
Welche am besten/schnellsten/die meisten Pythonic?
Deskriptoren sind genau dafür da. Also, * meiner Meinung nach * sollten Sie Deskriptoren verwenden. Ich habe dies absichtlich kursiv hervorgehoben, um zu verdeutlichen, dass dies hauptsächlich auf Meinungen beruht. Voting zu halten, wie in erster Linie auf der Grundlage von Meinungen – J0HN
Ich würde den Dekorateur auch empfehlen. Wenn Sie das jedoch mit einer Metaklasse kombinieren, können Sie automatisch die Namen der Klassenvariablen aufnehmen, um den Deskriptor zu erstellen, wodurch das Dictionary 'self.data' überflüssig wird. Das wäre etwas besser für Speicher- und Performance-Overhead, aber wahrscheinlich noch wichtiger, Sie müssten sich niemals mit Schlüsselkollisionen oder merkwürdigem Verhalten in dem Fall befassen, in dem der Referent stirbt. –