Seite 1 von 1
managed attributes
Verfasst: Donnerstag 19. November 2009, 10:07
von joh#
Hallo,
ich habe bei der v.2.6 folgendes versucht:
Code: Alles auswählen
>>> class CKl(object):
def __init__(self):
print"...Kontruktor..."
def get_p1(self):
print "...getter..."
return self.__p1
def set_p1(self, newval):
self.__p1=newval
print"...setter mit %d ..." % newval
__p1=property(get_p1, set_p1)
>>> m1=CKl()
...Kontruktor...
>>> m1.p1
Traceback (most recent call last):
File "<pyshell#20>", line 1, in <module>
m1.p1
AttributeError: 'CKl' object has no attribute 'p1'
>>> m1.__p1
Traceback (most recent call last):
File "<pyshell#21>", line 1, in <module>
m1.__p1
AttributeError: 'CKl' object has no attribute '__p1'
>>>
d.h. ein privates Attribut __p1 definiert mit setter und getter.
Wie kann ich es denn nun von außen ansprechen? (s.o. geht ja nicht)
Griß
joh
Verfasst: Donnerstag 19. November 2009, 10:20
von Darii
Wozu überhaupt solche trivialen getter und setter(und wenn dann benutzt man eher
properties dafür)? Und wozu benutzt du zwei Unterstriche(was nicht privat im Java-Sinne bedeutet) wenn du sowieso von außen drauf zugreifen willst?
Ansonsten benutze _CKl__p1 statt __p1.
Re: managed attributes
Verfasst: Donnerstag 19. November 2009, 10:22
von /me
joh# hat geschrieben:[...] ein privates Attribut __p1 definiert mit setter und getter.
Wie kann ich es denn nun von außen ansprechen? [...]
Ich gehe jetzt mal davon aus, dass das eine rein akademische Frage ist. Explizit privat deklarierte Methoden und Attribute sollte man wirklich nicht von außen ansprechen, denn sonst kann man sich das auch gleich ganz schenken.
Such mal in der Dokumentation unter
http://docs.python.org/reference/expressions.html nach "name mangling". Wenn du das Gelesene anwendest wirst du feststellen, dass du das Attribut mit m1._CKl__p1 ansprechen kannst. Den Folgefehler solltest du dir dann selber erklären können.
Re: managed attributes
Verfasst: Donnerstag 19. November 2009, 10:52
von bords0
Du willst vermutlich folgendes:
Code: Alles auswählen
>>> class CKl(object):
def __init__(self):
print"...Kontruktor..."
def get_p1(self):
print "...getter..."
return self._p1
def set_p1(self, newval):
self._p1=newval
print"...setter mit %s ..." % newval
p1=property(get_p1, set_p1)
(nicht wirklich getestet)
Verfasst: Donnerstag 19. November 2009, 11:01
von BlackJack
@joh#: Wenn man auf `__p1` normal zugreifen könnte, hättest Du ausserdem eine nette Endlosrekursion gebastelt. Eine Zuweisung an `__p1` würde `set_p()` aufrufen, was `__p1` etwas zuweist, was `set_p()` aufruft, was `__p1` etwas zuweist, was `set_p()` aufruft, …
"Managed attributes" heissen in Python übrigens "properties". Und doppelte führende Unterstriche sind in Python eher unüblich. Das ist zum Beispiel nützlich um Namenskollisionen bei Mehrfachvererbung zu vermeiden. Ansonsten gilt die Konvention, dass *ein* führender Unterstrich Implementierungsdetails kennzeichnet, die man von aussen nicht benutzen sollte.
Verfasst: Donnerstag 19. November 2009, 14:00
von joh#
BlackJack hat geschrieben:
"Managed attributes" heissen in Python übrigens "properties". Und doppelte führende Unterstriche sind in Python eher unüblich. Das ist zum Beispiel nützlich um Namenskollisionen bei Mehrfachvererbung zu vermeiden. Ansonsten gilt die Konvention, dass *ein* führender Unterstrich Implementierungsdetails kennzeichnet, die man von aussen nicht benutzen sollte.
Also ich habe
http://openbook.galileocomputing.de/pyt ... 9c0853ba45
(Tabelle 12.2 Namensschemata für öffentliche, private und geschützte Member ) gelesen.
joh
Re: managed attributes
Verfasst: Donnerstag 19. November 2009, 14:06
von joh#
bords0 hat geschrieben:Du willst vermutlich folgendes:
Code: Alles auswählen
>>> class CKl(object):
def __init__(self):
print"...Kontruktor..."
def get_p1(self):
print "...getter..."
return self._p1
def set_p1(self, newval):
self._p1=newval
print"...setter mit %s ..." % newval
p1=property(get_p1, set_p1)
(nicht wirklich getestet)
ok, ich wollte einfach mal "versteckte setter/getter" testen, allerdings
führt ein
dann zu
joh
Verfasst: Donnerstag 19. November 2009, 14:21
von Rebecca
Das hat BlackJack dir doch schon vorausgesagt und erklaert.
EDIT: Das OpenBook taugt nichts, such mal im Forum danach.
Re: managed attributes
Verfasst: Donnerstag 19. November 2009, 14:41
von /me
joh# hat geschrieben:
ok, ich wollte einfach mal "versteckte setter/getter" testen, allerdings
führt ein
dann zu
Tipp: Überleg mal, was das
in deinem Code wohl bewirkt.
Verfasst: Samstag 21. November 2009, 11:25
von joh#
Rebecca hat geschrieben:Das hat BlackJack dir doch schon vorausgesagt und erklaert.
EDIT: Das OpenBook taugt nichts, such mal im Forum danach.
ok, das mit dem OpenBook lesen war also keine so gute Idee...
Wie genau würde denn nun das dortige Beispiel "Konto" in
wohlgefälligem Python aussehen (das Beispiel an sich, fand ich schon
nicht schlecht, nur muß es ebene funktionieren) Vielleicht hat das
hier im Forum schon mal jemand 'übersetzt'?
joh
Verfasst: Samstag 21. November 2009, 11:36
von Darii
joh# hat geschrieben:ok, das mit dem OpenBook lesen war also keine so gute Idee...
Wie genau würde denn nun das dortige Beispiel "Konto" in
wohlgefälligem Python aussehen (das Beispiel an sich, fand ich schon
nicht schlecht, nur muß es ebene funktionieren) Vielleicht hat das
hier im Forum schon mal jemand 'übersetzt'?
joh
So:
Code: Alles auswählen
class Konto(object):
def __init__(self, inhaber, kontonummer, kontostand,
max_tagesumsatz=1500):
self.inhaber = inhaber
self.kontonummer = kontonummer
self.kontostand = kontostand
self.max_tagesumsatz = max_tagesumsatz
self.umsatz_heute = 0 def geldtransfer(self, ziel, betrag):
# diese Methoden sind ok(bloß die Instanzvariablen müssten angepasst werden):
def einzahlen(self, betrag):
pass
def auszahlen(self, betrag):
pass
def zeige_konto(self):
pass
Die getter und setter sind in dem Beispiel überflüssig. Da es allerdings ein Beispiel ist, kann man sie trotzdem verwenden wenn man möchte. Ich habe allerdings den Eindruck, dass du noch nicht verstanden hast, warum dein Code nicht funktioniert.
Du definierst __p1 als property, in der setter-Funktion greifst du aber auf eben dieses __p1 wieder zu, wodurch die Funktion erneut aufgerufen wird. Also, definieren eine property als p1 und nicht als __p1.
Verfasst: Samstag 21. November 2009, 14:58
von joh#
Darii hat geschrieben:So:
. . .
Danke, das funktioniert.
Darii hat geschrieben:
Die getter und setter sind in dem Beispiel überflüssig. Da es allerdings ein Beispiel ist, kann man sie trotzdem verwenden wenn man möchte. Ich habe allerdings den Eindruck, dass du noch nicht verstanden hast, warum dein Code nicht funktioniert.
Das mit der (ungewollt erschaffenen) Rekursion ist jetzt schon verstanden.
Darii hat geschrieben:
Also, definieren eine property als p1 und nicht als __p1.
Ich glaube die Leute aus dem OpenBook wollten sagen: "Greife nie direkt auf die Attribute eines Objekts zu, aber es geht trotzdem durch einen impliziten Aufruf einer setter/getter Methode kann dabei auch etwa die gleiche Sicherheit wie beim expliziten Methodenaufruf erreicht werden"
Dabei kam allerdings etwas Konfusion rein wegen der falschen Unterstriche.
Vorausgesetzt es verstößt nicht gegen den guten Python Stil wie würde so ein impliziter
Aufruf für
denn dann codiert
Verfasst: Samstag 21. November 2009, 15:25
von BlackJack
@joh#: Nur mal so sprachlich: Methoden sind auch Attribute von Objekten. Diese harte Trennung zwischen "das sind Daten" und "das ist Code" gibt es in Python nicht. Alles was an einen Namen gebunden wird, kann auch als Datum behandelt werden. Also zum Beispiel in Datenstrukturen gesteckt oder als Argumente übergeben werden. Alles sind Objekte; und einige sind halt aufrufbar und andere nicht.
``k1.kontostand = 23000`` würde man wahrscheinlich eher nicht schreiben, weil ein Konto normalerweise über die Operationen darauf manipuliert wird, und das setzen eines fixen Betrags ausser beim Anlegen in der Regel nicht vorkommen sollte. Konten werden durch Ein- und Auszahlungen manipuliert. Das Attribut ist also semantisch nur zum Abfragen da. Was nicht heisst, dass man das setzen durch `property()`\s verhindern muss. Es reicht das zu dokumentieren. Wem das zu "unsicher" ist, für den ist Python wahrscheinlich nicht die richtige Programmiersprache.
Verfasst: Samstag 21. November 2009, 17:02
von Darii
joh# hat geschrieben:Ich glaube die Leute aus dem OpenBook wollten sagen: "Greife nie direkt auf die Attribute eines Objekts zu, aber es geht trotzdem durch einen impliziten Aufruf einer setter/getter Methode kann dabei auch etwa die gleiche Sicherheit wie beim expliziten Methodenaufruf erreicht werden"
Die vom Openbook haben einfach nur versucht unreflektiert Java-Konzepte auf Python zu übertragen. Ein trivialer getter/setter(der nichts weiter tut als den Wert selbst zuzuweisen) ist in Python unnötig, da man in Python, wenn es später nötig ist, transparent(d.h. ohne die Schnittstelle zu verändern) den Attributzugriff durch eine property ersetzen kann. Das geht ihn Java nicht, zudem gibt es Sachen wie
JavaBeans Properties. Kurz: In Java muss man einfach quasi immer getter/setter verwenden.
Getter/setter, die nicht weiter tun als den Typ zu überprüfen sind in Python auch meist überflüssig, da wäre es besser gleich eine Sprache mit statischer Typisierung zu verwenden wenn einem das zu Heikel ist.