[Python-de] Re: Indirekter Funktionsaufruf

Gerhard Häring gerhard.haering at opus-gmbh.net
Wed Jan 22 10:54:39 EST 2003


Oliver Vecernik <vecernik=Tswl7xcH0yE at public.gmane.org> wrote:
> Hallo Leute!
> 
> Ich habe in einer Datenbank eine Tabelle mit Funktionsnamen in einem 
> Textfeld.
> 
> mms=# \d imports
>            Table "imports"
>     Column    |  Type   | Modifiers
> -------------+---------+-----------
>   func        | text    | not null
>   url         | text    |
>   last_update | date    |
>   active      | boolean |
> Primary key: imports_pkey
> 
> mms=# select func from imports;
>    func
> ---------
>   iso3166
>   mab
>   plzv
> (3 rows)
> 
> 
> Diese Funktionen sollen der Reihe nach aufgerufen werden:
> 
> ...
> 
> class MMS:
> 
>      def __init__(self):
>          self.cx = PgSQL.connect('localhost::mms')
>          self.cu = self.cx.cursor()
> 
>      def __del__(self):
>          self.cu.close()
>          self.cx.close()
> 
>      def read_functions(self):
>          self.cu.execute("SELECT func FROM imports WHERE active = TRUE");
>          return self.cu.fetchall()

fetchall() liefert eine Liste von PgResultSets. PgResultSets sind komfortabler
als die Listen bzw. Tupels die andere Datenbankmodule zurückliefern, weil man
mit ihnen direkt (ohne einen extra Wrapper zu brauchen) auf die Spalten über
den Namen zugreifen kann.

> ...
> 
> def main():
>      db = MMS()
>      imports = db.read_functions()
>      for func in imports:
>          apply(func)

So geht's:

#v+
for func_record in imports:
    func_name = func_record.func
    # oder func_name = func_record["func"]
    # oder func_name = func_record[0]
    # nur die letzte Möglichkeit ist auf andere DB-API Module portierbar
    # die ersten beiden sind pyPgSQL-spezifisch

    # so, jetzt die Funktion ausführen - nehmen wir an, die Funktionen
    # liegen im aktuellen Modul, also zuerst das aktuelle Modul rausfinden:
    import sys
    cur_module = sys.modules[__name__]

    # jetzt die Funktion holen
    func = getattr(cur_module, func_name)

    # jetzt die Funktion ausführen
    func()
#v-

Das Ganze kann man natürlich ohne temporäre Variablen ein wenig kompakter
schreiben.

Übrigens macht apply etwas ganz anderes, es wendet eine Liste von
Parametern auf eine Funktion an:

#v+
>>> def add(x,y): return x+y
...
>>> print apply(add, [3,4])
7
#v-

apply ist aber seit Python 2.0 unnötig:

#v+
>>> params = [3,4]
>>> print add(*params)
7
#v-

Du suchtest wohl eher "exec" oder "eval", aber auch die sind in den meisten
Fällen mindestens unnötig :-)

>      del db

del kannst du dir in Python meistens sparen. Python hat Garbage Collection
;-)

Gerhard
-- 
Gerhard Häring
OPUS GmbH München
Tel.: +49 89 - 889 49 7 - 32
http://www.opus-gmbh.net/





More information about the Python-de mailing list