Aufruf einer Methode ohne () am ende???

Wenn du dir nicht sicher bist, in welchem der anderen Foren du die Frage stellen sollst, dann bist du hier im Forum für allgemeine Fragen sicher richtig.
Antworten
Benutzeravatar
jens
Python-Forum Veteran
Beiträge: 8502
Registriert: Dienstag 10. August 2004, 09:40
Wohnort: duisburg
Kontaktdaten:

.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???

GitHub | Open HUB | Xing | Linked in
Bitcoins to: 1JEgSQepxGjdprNedC9tXQWLpS424AL8cd
mitsuhiko
User
Beiträge: 1790
Registriert: Donnerstag 28. Oktober 2004, 16:33
Wohnort: Graz, Steiermark - Österreich
Kontaktdaten:

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:

Code: Alles auswählen

lastrowid = property(lambda s: s._lastrowid())
TUFKAB – the user formerly known as blackbird
Benutzeravatar
jens
Python-Forum Veteran
Beiträge: 8502
Registriert: Dienstag 10. August 2004, 09:40
Wohnort: duisburg
Kontaktdaten:

blackbird hat geschrieben:

Code: Alles auswählen

lastrowid = property(lambda s: s._lastrowid())
Das liefert mit nur ein <property object at 0x81df064> zurück, aber nicht wirklich den Wert...

GitHub | Open HUB | Xing | Linked in
Bitcoins to: 1JEgSQepxGjdprNedC9tXQWLpS424AL8cd
mitsuhiko
User
Beiträge: 1790
Registriert: Donnerstag 28. Oktober 2004, 16:33
Wohnort: Graz, Steiermark - Österreich
Kontaktdaten:

jens hat geschrieben:
blackbird hat geschrieben:

Code: Alles auswählen

lastrowid = property(lambda s: s._lastrowid())
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.
TUFKAB – the user formerly known as blackbird
mitsuhiko
User
Beiträge: 1790
Registriert: Donnerstag 28. Oktober 2004, 16:33
Wohnort: Graz, Steiermark - Österreich
Kontaktdaten:

Code: Alles auswählen

class Cursor(object):

    def __init__(self, lastrowid):
        self._lastrowid = lastrowid

    lastrowid = property(lambda s: s._lastrowid)
So gehts
TUFKAB – the user formerly known as blackbird
BlackJack

Jetzt musst Du nur noch das überflüssige ``lambda`` rausnehmen.
mitsuhiko
User
Beiträge: 1790
Registriert: Donnerstag 28. Oktober 2004, 16:33
Wohnort: Graz, Steiermark - Österreich
Kontaktdaten:

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.
TUFKAB – the user formerly known as blackbird
Benutzeravatar
jens
Python-Forum Veteran
Beiträge: 8502
Registriert: Dienstag 10. August 2004, 09:40
Wohnort: duisburg
Kontaktdaten:

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?

GitHub | Open HUB | Xing | Linked in
Bitcoins to: 1JEgSQepxGjdprNedC9tXQWLpS424AL8cd
mitsuhiko
User
Beiträge: 1790
Registriert: Donnerstag 28. Oktober 2004, 16:33
Wohnort: Graz, Steiermark - Österreich
Kontaktdaten:

property ist einfacher. aber im dict cursor will ich ja direkt alles weiterleiten.
TUFKAB – the user formerly known as blackbird
Benutzeravatar
jens
Python-Forum Veteran
Beiträge: 8502
Registriert: Dienstag 10. August 2004, 09:40
Wohnort: duisburg
Kontaktdaten:

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* :lol:

Das hab ich jetzt in die echte Klasse eingebaut: http://www.python-forum.de/viewtopic.php?p=29014#29014

GitHub | Open HUB | Xing | Linked in
Bitcoins to: 1JEgSQepxGjdprNedC9tXQWLpS424AL8cd
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.
Antworten