Seite 1 von 1
Aufruf einer Methode ohne () am ende???
Verfasst: Donnerstag 12. Januar 2006, 14:28
von jens
.oO(Ob der Betreff das richtige Ausdrückt?!?)
Ich hab ja ein
mysqldb Problem. In dem Zusammenhang hier nochmal eine allgemeine Frage.
Hier mal ein Beispiel:
Code: Alles auswählen
import time
class cursor:
def __init__(self):
self.lastrowid = self._lastrowid()
def _lastrowid(self):
return time.time()
cursor = cursor()
print cursor.lastrowid
time.sleep(0.3)
print cursor.lastrowid
time.sleep(0.3)
print cursor.lastrowid
Das Funktioniert so natürlich nicht. Normalerweise müßte die Zeit halt, um 0.3 unterschiedlich sein, sind sie aber nicht, weil nur bei __init__ die Zeit dem String zugewiesen wird und nicht beim print-Anweisung selbst.
Ich kann aber kein cursor.lastrowid() machen...
Wie kann ich einen Funktionsaufruf machen, obwohl ich nur statt lastrowid
() ein lastrowid mache???
Verfasst: Donnerstag 12. Januar 2006, 14:33
von mitsuhiko
was soll denn das sein?
probiers mal so:
Code: Alles auswählen
class Cursor(object):
def __init__(self, cursor):
self._cursor = cursor
def __getattr__(self, attr):
_attr = getattr(self._cursor, attr)
if _attr == 'lastrowid':
return _attr()
return attr
Oder machs mit properties:
Verfasst: Donnerstag 12. Januar 2006, 15:00
von jens
blackbird hat geschrieben:
Das liefert mit nur ein
<property object at 0x81df064> zurück, aber nicht wirklich den Wert...
Verfasst: Donnerstag 12. Januar 2006, 15:07
von mitsuhiko
jens hat geschrieben:blackbird hat geschrieben:
Das liefert mit nur ein
<property object at 0x81df064> zurück, aber nicht wirklich den Wert...
Kindskopf. Geht ja nur, wenn man das an eine Instanz bindet.
Verfasst: Donnerstag 12. Januar 2006, 15:08
von mitsuhiko
Code: Alles auswählen
class Cursor(object):
def __init__(self, lastrowid):
self._lastrowid = lastrowid
lastrowid = property(lambda s: s._lastrowid)
So gehts
Verfasst: Donnerstag 12. Januar 2006, 23:19
von BlackJack
Jetzt musst Du nur noch das überflüssige ``lambda`` rausnehmen.
Verfasst: Freitag 13. Januar 2006, 04:45
von mitsuhiko
BlackJack hat geschrieben:Jetzt musst Du nur noch das überflüssige ``lambda`` rausnehmen.
Jetzt musst Du nur noch erklären warum ``lambda`` überflüssig ist.
Verfasst: Freitag 13. Januar 2006, 08:30
von jens
Also
der fertige Work-a-Round geht momentan über __getattr__ ganz gut:
Code: Alles auswählen
import time
class cursor:
def __getattr__(self, attr):
if attr == 'lastrowid':
return self._lastrowid()
return getattr(self._cursor, attr)
def _lastrowid(self):
return time.time()
cursor = cursor()
print cursor.lastrowid
time.sleep(0.3)
print cursor.lastrowid
time.sleep(0.3)
print cursor.lastrowid
Das ganze über property:
Code: Alles auswählen
import time
class cursor:
def _lastrowid(self):
return time.time()
lastrowid = property(_lastrowid)
cursor = cursor()
print cursor.lastrowid
time.sleep(0.3)
print cursor.lastrowid
time.sleep(0.3)
print cursor.lastrowid
Und da wir schon mal dabei sind... Was ist besser, __getattr__ oder property???
Mir erscheint property um einiges einfacher zu sein
EDIT: Mir fällt gerade ein, das es in meinem Fall nicht so einfach mit property gehen wird... Ich würde ja immer das evtl. schon vorhandene .lastrowid überschreiben. Ich müßte also erstmal nach prüfen ob .lastrowid nicht existiert und dann erst mein eigenes implementieren... Aber wie geht das?
Zum anderen, existiert ich in meinem Fall eh ein __getattr__.
EDIT2: So kann es aber doch gehen:
Code: Alles auswählen
import time
class cursor:
def _lastrowid(self):
return time.time()
if not hasattr(cursor, "lastrowid"):
cursor.lastrowid = property(cursor._lastrowid)
c = cursor()
print c.lastrowid
time.sleep(0.3)
print c.lastrowid
time.sleep(0.3)
print c.lastrowid
Ist aber auch nicht so optimal, weil die if-Geschichte auf Modulebene passiert...
Tipps?
Verfasst: Freitag 13. Januar 2006, 10:35
von mitsuhiko
property ist einfacher. aber im dict cursor will ich ja direkt alles weiterleiten.
Verfasst: Freitag 13. Januar 2006, 10:42
von jens
blackbird hat geschrieben:property ist einfacher. aber im dict cursor will ich ja direkt alles weiterleiten.
Ich weiß... Deswegen ich aber auch die letzte Version IMHO auch die Beste. Weil dann halt einmal nachgesehen wird, ob lastrowid existiert oder nicht... In der anderen Variante wird es bei jedem Zugriff gemacht...
Nur, ich finde es nicht gut, das ich es auf Module-Ebene mache... ...überleg... So wird ein Schuh draus:
Code: Alles auswählen
import time
class cursor:
def __init__(self):
if not hasattr(cursor, "lastrowid"):
cursor.lastrowid = property(cursor._lastrowid)
def _lastrowid(self):
return time.time()
c = cursor()
print c.lastrowid
time.sleep(0.3)
print c.lastrowid
time.sleep(0.3)
print c.lastrowid
So ist das doch wirklich optimal!!! *freu*
Das hab ich jetzt in die echte Klasse eingebaut:
http://www.python-forum.de/viewtopic.php?p=29014#29014
Verfasst: Freitag 13. Januar 2006, 22:47
von BlackJack
blackbird hat geschrieben:BlackJack hat geschrieben:Jetzt musst Du nur noch das überflüssige ``lambda`` rausnehmen.
Jetzt musst Du nur noch erklären warum ``lambda`` überflüssig ist.
Ich ging davon aus, das `_lastrowid` der Name einer "getter" Methode ist. Dann braucht man die nicht nochmal in einer anonymen Funktion zu kapseln um sie mit `property()` zu verwenden.