Seite 1 von 1

Funktionsnamen auslesen?

Verfasst: Donnerstag 29. November 2007, 18:54
von meneliel
Einen wunderschönen Guten Abend,

eigentlich hat die Suchfunktion mein Problem ja schon gelöst:
CM hat geschrieben:Hi
na, den Funktionsnamen kannst Du natürlich auch auf einer anderen Ebene erhalten:

Code: Alles auswählen

>>> foo.__name__
'foo'
Im Grunde genommen aber weißt Du ohnehin den Namen der Funktion, die Du aufrufst, oder?

Gruß,
Christian
(Irgendwo hier gefunden)

Allerdings hat mich der letzte Satz noch auf eine Idee gebracht:

Problem:
Angenommen, ich weiß den Namen nicht?

Also ich habe mehrere Funktionen in meinem Script, die irgendwie alle ähnlich sind und ca 2/3 vom Code identisch sind... bietet sich also an, dass so zu kürzen, dass nur die unterschiedlichen Teile in die jeweilige Funktion kommen.

Also hab ich jetzt alle Funktionsnamen in eine Liste gepackt, und geh die durch.
Mit dem funktion.__name__ krieg ich ja dann den Namen und kann nacheinander die ganzen Funktionen aufrufen, und die Teiel die identisch sind zusammenpacken (in meinem Fall den User zur Eingabe des entsprechenden Pfades/Files bitten (welches krieg ich ja nun raus, mit dem Funktionsnamen), das entsprechende File öffnen und einlesen...

Dann öffne ich die einzelnen Funktionen um die Dateien in meine Datenbank einzulesen, da diese in unterschiedliche Tabellen, mit unterschiedlichen Attributen kommen, muss ich zumindest das

Code: Alles auswählen

cursor.execute('INSERT INTO ........')
in den einzelnen Funktionen lassen.

Jedenfalls: Gibt es JETZT eine Möglichkeit, irgendwie herauszubekommen welche Funktionen es alles gibt, innerhalb eines Scriptes und diese dann in eine Liste zu bekommen? Sonst müsste ich jetzt, bei einer weiteren Funktion, die dazu kommt, jedesmal die Liste manuell erweitern. (Ist zwar nicht das Problem und ich glaube auch nicht, dass das passiert, aber würde mich trotzdem interessieren on und wie das möglich wäre.

Verfasst: Donnerstag 29. November 2007, 20:03
von nkoehring
spontan fiele mir da exec ein...

also sowas wie

Code: Alles auswählen

script = file(filename, "r")read.()
sandbox = dict()
exec script in sandbox
...in sandbox stehen dann alle Variablen, Funktionen, usw drin. Allerdings fuehrst du das Script dann auch aus. Es gibt dafuer aber auch noch ein Debugging-Modul...

Verfasst: Donnerstag 29. November 2007, 20:08
von Jan-Peer
Vielleicht wäre die dir() Funktion ein erster Ansatzpunkt. Die zeigt zwar noch ein bisschen was anderes an, aber vielleicht kannst du das rausfiltern ...

Verfasst: Donnerstag 29. November 2007, 20:26
von tiax

Re: Funktionsnamen auslesen?

Verfasst: Donnerstag 29. November 2007, 20:29
von BlackJack
meneliel hat geschrieben:Also hab ich jetzt alle Funktionsnamen in eine Liste gepackt, und geh die durch.
Warum hast Du da die Namen hineingepackt und nicht gleich die Funktionen selbst?
Jedenfalls: Gibt es JETZT eine Möglichkeit, irgendwie herauszubekommen welche Funktionen es alles gibt, innerhalb eines Scriptes und diese dann in eine Liste zu bekommen? Sonst müsste ich jetzt, bei einer weiteren Funktion, die dazu kommt, jedesmal die Liste manuell erweitern. (Ist zwar nicht das Problem und ich glaube auch nicht, dass das passiert, aber würde mich trotzdem interessieren on und wie das möglich wäre.
Wenn mit Skript die ausgeführte Datei gemeint ist, kann man es als `__main__` importieren und mit dem `inspect`-Modul nachschauen. Wenn Du mindestens eine Funktion oder Klasse im Modul kennst, kannst Du über das auch an das Modul heran kommen.

Code: Alles auswählen

import __main__
import inspect

def test_a():
    pass

def test_b():
    pass

print inspect.getmembers(__main__, inspect.isfunction)

# Alternativ:

print inspect.getmembers(inspect.getmodule(test_a), inspect.isfunction)

Re: Funktionsnamen auslesen?

Verfasst: Donnerstag 29. November 2007, 20:50
von meneliel
BlackJack hat geschrieben:
meneliel hat geschrieben:Also hab ich jetzt alle Funktionsnamen in eine Liste gepackt, und geh die durch.
Warum hast Du da die Namen hineingepackt und nicht gleich die Funktionen selbst?
Hab das so gemacht:

Code: Alles auswählen

tab = (indicator_description,indicator_catagories,ebenen)

for fill in tab:
  csv_file = raw_input(fill.__name__ +':\n')
  # Wenn csv_file ein Directory ist
  if not os.path.isfile(csv_file): 
    csv_List = os.listdir(csv_file)
    for element in csv_List:
      f = file(csv_List +"/"+element)
  # csv_file ist ein File    
  else:
    f = file(csv_file)
  # Aufruf der Funktion i mit csv.reader(f)
  reader_csv = csv.reader(f, delimiter=';')
  fill(reader_csv)

Re: Funktionsnamen auslesen?

Verfasst: Freitag 30. November 2007, 15:45
von meneliel
BlackJack hat geschrieben:
meneliel hat geschrieben:Also hab ich jetzt alle Funktionsnamen in eine Liste gepackt, und geh die durch.
Warum hast Du da die Namen hineingepackt und nicht gleich die Funktionen selbst?
Na ich hab die Namen ja nicht als Str übergeben, sondern schon die Funktion selber und nur die Klammern weggelassen.
Wenn mit Skript die ausgeführte Datei gemeint ist, kann man es als `__main__` importieren und mit dem `inspect`-Modul nachschauen. Wenn Du mindestens eine Funktion oder Klasse im Modul kennst, kannst Du über das auch an das Modul heran kommen.

Code: Alles auswählen

import __main__
import inspect

def test_a():
    pass

def test_b():
    pass

print inspect.getmembers(__main__, inspect.isfunction)

# Alternativ:

print inspect.getmembers(inspect.getmodule(test_a), inspect.isfunction)
Hab das getestet und ein bisschen rumgespielt.
Da bekomme ich die Namen dann aber als String ausgegeben. Aber da kann ich ja dann die Funktion nicht mehr aufrufen. Weil ist ja nen String ...

Code: Alles auswählen

inspect.getmembers(__main__, inspect.isfunction)[0][0]()

Traceback (most recent call last):
  File "<string>", line 1, in <string>
TypeError: 'str' object is not callable
... logischer Weise ... hab es trotzdem probiert, falls ich mich irre ...
...

noch as probiert ...

Code: Alles auswählen

eval(inspect.getmembers(__main__, inspect.isfunction)[0][0])()
:D aber so geht es ... :) Also das eval hab ich bis jetzt noch nich gekannt nur gerade beim Suchen gefunden... was macht das eval genau? Wenn mein String eigentlich irgendein Objekt ist, wird es einfach kein String mehr? (komischer Satz ... :oops: ) Weil, wenn ich das auf eine beliebige Zeichenkette anwende, dann funktioniert das nicht und es kommt:
"NameError: name 'a' is not defined" (wobei a, ganz unkreativ mal die beliebige Zeichenkette ist .... )

Verfasst: Freitag 30. November 2007, 15:54
von Leonidas
`eval` führt den Code aus, daher ist es nicht so schlau dass du das nutzt.

Besser so:

Code: Alles auswählen

>>> def f(): pass
... 
>>> import __main__
>>> getattr(__main__, 'f')
<function f at 0x2b6bf9bbd8c0>
Also brauchst du erstmal eine Referenz auf den Ort wo die Funktion definiert ist.

Verfasst: Freitag 30. November 2007, 15:56
von meneliel
Sorry, wegen Doppelpost:

So sieht es jetzt aus :)

Code: Alles auswählen

for fill in (inspect.getmembers(__main__, inspect.isfunction)):
  csv_file = raw_input(fill[0]+':\n')
  # Wenn csv_file ein Directory ist
  if not os.path.isfile(csv_file): 
    csv_List = os.listdir(csv_file)
    for element in csv_List:
      f = file(csv_List +"/"+element)
  # csv_file ist ein File    
  else:
    f = file(csv_file)
  # Aufruf der Funktion fill mit csv.reader(f)
  reader_csv = csv.reader(f, delimiter=';')
  eval(fill[0])(reader_csv)  

Verfasst: Freitag 30. November 2007, 16:40
von BlackJack
`getmembers()` gibt keine Zeichenketten sondern Tupel zurück, die den Namen *und* das Objekt enthalten. Also kein Grund auf `eval` zurück zu greifen.

Verfasst: Freitag 30. November 2007, 17:01
von meneliel
Leonidas hat geschrieben:`eval` führt den Code aus, daher ist es nicht so schlau dass du das nutzt.
ups... okay... :oops:
Leonidas hat geschrieben: Besser so:

Code: Alles auswählen

>>> def f(): pass
... 
>>> import __main__
>>> getattr(__main__, 'f')
<function f at 0x2b6bf9bbd8c0>
Also brauchst du erstmal eine Referenz auf den Ort wo die Funktion definiert ist.


Das versteh ich jetzt nicht so ganz :( Funktionen hab ich ja schon, die stehen im Code mit drin.... hab die nur nicht mit gepostet. Wozu brauch ich das getattr() in dem Fall?

Und mit dem inspect.getmembers(__main__, inspect.isfunction) komm ich doch auch an die ran....
BlackJack hat geschrieben:`getmembers()` gibt keine Zeichenketten sondern Tupel zurück, die den Namen *und* das Objekt enthalten. Also kein Grund auf `eval` zurück zu greifen.
Nochmal *ooops*. Okay, notiere: eval ist böse .... nicht benutzen ...

Da nun der ganze Code: http://paste.pocoo.org/show/13376/
Musste ja jetzt praktisch nur die letzte Zeile ändern in:

Code: Alles auswählen

fill[1](reader_csv)
Danke.

Verfasst: Freitag 30. November 2007, 17:25
von Leonidas
meneliel hat geschrieben:Das versteh ich jetzt nicht so ganz :( Funktionen hab ich ja schon, die stehen im Code mit drin.... hab die nur nicht mit gepostet. Wozu brauch ich das getattr() in dem Fall?
Wenn du den Namen vom Attribut hast (ob das nun eine Funktion ist oder was auch immer), kannst du mit `getattr()` das an dieses Attribut gebundene Objekt bekommen.