Funktionsnamen auslesen?

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
meneliel
User
Beiträge: 256
Registriert: Montag 25. Juni 2007, 08:35
Kontaktdaten:

Donnerstag 29. November 2007, 18:54

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.
Benutzeravatar
nkoehring
User
Beiträge: 543
Registriert: Mittwoch 7. Februar 2007, 17:37
Wohnort: naehe Halle/Saale
Kontaktdaten:

Donnerstag 29. November 2007, 20:03

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...
[url=http://www.python-forum.de/post-86552.html]~ Wahnsinn ist auch nur eine andere Form der Intelligenz ~[/url]
hackerkey://v4sw6CYUShw5pr7Uck3ma3/4u7LNw2/3TXGm5l6+GSOarch/i2e6+t2b9GOen7g5RAPa2XsMr2
Jan-Peer
User
Beiträge: 166
Registriert: Dienstag 2. Oktober 2007, 10:55

Donnerstag 29. November 2007, 20:08

Vielleicht wäre die dir() Funktion ein erster Ansatzpunkt. Die zeigt zwar noch ein bisschen was anderes an, aber vielleicht kannst du das rausfiltern ...
Benutzeravatar
tiax
User
Beiträge: 152
Registriert: Samstag 23. Juli 2005, 17:28
Kontaktdaten:

Donnerstag 29. November 2007, 20:26

Ne invoces expellere non possis
[url=xmpp://florian@florianheinle.de]xmpp:florian@florianheinle.de[/url]
BlackJack

Donnerstag 29. November 2007, 20:29

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)
meneliel
User
Beiträge: 256
Registriert: Montag 25. Juni 2007, 08:35
Kontaktdaten:

Donnerstag 29. November 2007, 20:50

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)
meneliel
User
Beiträge: 256
Registriert: Montag 25. Juni 2007, 08:35
Kontaktdaten:

Freitag 30. November 2007, 15:45

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 .... )
Leonidas
Administrator
Beiträge: 16024
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

Freitag 30. November 2007, 15:54

`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.
My god, it's full of CARs! | Leonidasvoice vs Modvoice
meneliel
User
Beiträge: 256
Registriert: Montag 25. Juni 2007, 08:35
Kontaktdaten:

Freitag 30. November 2007, 15:56

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)  
BlackJack

Freitag 30. November 2007, 16:40

`getmembers()` gibt keine Zeichenketten sondern Tupel zurück, die den Namen *und* das Objekt enthalten. Also kein Grund auf `eval` zurück zu greifen.
meneliel
User
Beiträge: 256
Registriert: Montag 25. Juni 2007, 08:35
Kontaktdaten:

Freitag 30. November 2007, 17:01

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.
Zuletzt geändert von meneliel am Samstag 1. Dezember 2007, 13:01, insgesamt 1-mal geändert.
Leonidas
Administrator
Beiträge: 16024
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

Freitag 30. November 2007, 17:25

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.
My god, it's full of CARs! | Leonidasvoice vs Modvoice
Antworten