Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > de.comp.lang.python > #5639
| From | Peter Otten <__peter__@web.de> |
|---|---|
| Newsgroups | de.comp.lang.python |
| Subject | Re: [Python-de] "property-init"-decorator |
| Date | 2020-05-27 17:13 +0200 |
| Organization | None |
| Message-ID | <mailman.155.1590592405.27263.python-de@python.org> (permalink) |
| References | <875zci8zut.fsf@orrococo> <c36dda0a-50b6-7454-2da4-1f3bff5828cf@goebel-consult.de> <4719790.vIyLdRSyTD@palindrom> |
Am Mi Mai 27 2020, 10:27:31 schrieb Hartmut Goebel:
> Am 26.05.20 um 17:44 schrieb Оlе Ѕtrеісhеr:
> > Wie bringt man die enger zusammen? Ein @myprop.init gibt es ja
> > offensichtlich nicht und kann man auch nicht so ohne weiteres anlegen,
> > oder? Oder was wäre ein sinnvolles Pattern hier?
>
> Du könntest eine eigene "Property" class implementieren, die einen
> weiteren Docorator "initialisiere" hat. Allerdings bleibt immer noch
> das Problem, dass Du diese Funktion in __init__ irgendwie aufrufen
> musst. Du müsstest in __init__ hergehen und alle properies der Klasse
> (self.__class__) finden und deren initalizer aufrufen.
>
> Ich habe die genau Funktionsweise von Properties nicht im Kopf, aber
> irgendwie sollte das gehen. Vielleicht schaust Du man in den PEP zu
> properties, dort gibt es sicher Details.
>
> Allerdings gibt es mindestens zwei Haken:
>
> 1. Wenn die initializer in eine bestimmten Reihenfolge aufgerufen werden
> müssen, dann musst Du sie doch wieder benennen. Denn sonst bekommstt Du
> keine Reihenfolge.
Die Reihenfolge kann durch die Positionierung in der Klasse bestimmt werden:
>>> class A:
... foo = 1
... bar = 2
...
>>> class B:
... bar = 2
... foo = 1
...
>>> vars(A).keys()
dict_keys(['__module__', 'foo', 'bar', '__dict__', '__weakref__', '__doc__'])
>>> vars(B).keys()
dict_keys(['__module__', 'bar', 'foo', '__dict__', '__weakref__', '__doc__'])
>
> 2. Wie ruft man die iniatlizer überhaupt auf?
Da benötigt man die Mithilfe der Eigentümer(meta)klasse.
Nachfolgend eine einfache Implementierung, die die Properties anhand ihrer
Klasse identifiziert:
$ cat init_property.py
missing = object()
class myproperty(property):
finit = None
default = missing
def initializer(self, f):
self.finit = f
return self
def init(self, owner):
if self.finit is not None:
self.finit(owner)
elif self.default is not missing:
# eventuell "_" + self.name, um den Aufruf des Setters
# zu vermeiden
setattr(owner, self.name, self.default)
def __set_name__(self, owner, name):
self.name = name
class Cfg:
@classmethod
def myproperties(cls):
return [p for p in vars(cls).values() if isinstance(p, myproperty)]
def __init__(self):
for p in self.myproperties():
p.init(self)
@myproperty
def foo(self):
return self._foo
@foo.setter
def foo(self, value):
assert 0 <= value < 100
self._foo = value
@foo.initializer
def foo(self):
self._foo = 42
@myproperty
def bar(self):
return self._bar
@bar.setter
def bar(self, value):
assert isinstance(value, int)
self._bar = value
bar.default = 123
c = Cfg()
print(c.foo) # 42, im Initializer gesetzt
print(c.bar) # 123, default-Attribut
c.foo = 24 # OK
c.bar = "spam" # Exception
$ python3.8 init_property.py
42
123
Traceback (most recent call last):
File "init_property.py", line 59, in <module>
c.bar = "spam"
File "init_property.py", line 50, in bar
assert isinstance(value, int)
AssertionError
$
Wer's gerne eleganter hätte, könnte sich ja mal den Quellcode der dataclasses
zu Gemüte führen...
Back to de.comp.lang.python | Previous | Next — Previous in thread | Next in thread | Find similar
"property-init"-decorator ole-usenet-spam@gmx.net (Оlе Ѕtrеісhеr) - 2020-05-26 17:44 +0200 Re: [Python-de] "property-init"-decorator Julian Gethmann <mail.python.org@gethmann.org> - 2020-05-26 18:07 +0200 Re: [Python-de] "property-init"-decorator Hartmut Goebel <h.goebel@goebel-consult.de> - 2020-05-27 10:27 +0200 Re: "property-init"-decorator "Andreas B." <ab@sysing.de> - 2020-05-27 13:18 +0200 Re: [Python-de] "property-init"-decorator Gregor Engberding <gregor@landit.de> - 2020-05-27 17:04 +0200 Re: [Python-de] "property-init"-decorator Peter Otten <__peter__@web.de> - 2020-05-27 17:13 +0200 Re: [Python-de] "property-init"-decorator Hartmut Goebel <h.goebel@goebel-consult.de> - 2020-05-31 10:13 +0200 Re: [Python-de] "property-init"-decorator Peter Otten <__peter__@web.de> - 2020-05-31 15:37 +0200
csiph-web