[C API] Durch alle Funktionen iterieren

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
theliquidwave
User
Beiträge: 221
Registriert: Sonntag 1. Juni 2008, 09:08

Hallo.
Ich suche gerade eine Möglichkeit, per C-API jede Funktion einer Pythondatei zu durchlaufen.
Basis könnte dabei folgendes Beispielskript sein: http://docs.python.org/extending/embedd ... -embedding
Einziger Unterschied: Ich habe keinen Funktionsnamen den ich aufrufen kann, sondern ich möchte gerne alle Funktionsnamen auslesen.
Also ähnlich wie dir(modulename)

Gruß
Grüßle.
derdon
User
Beiträge: 1316
Registriert: Freitag 24. Oktober 2008, 14:32

Zwar nicht mit der C-API, aber vllt is pure-Python auch ok:

Code: Alles auswählen

>>> from StringIO import StringIO
>>> import ast
>>> from itertools import ifilter
>>> file_content = StringIO('''def foo(arg1, arg2):
...     pass
... def bar(*args, **kwargs):
...     pass
... def baz(blub=23, blab=42):
...     pass
... ''')
>>> def yield_functions(expression):
...     '''return every node, which resembles a function, of a given `expression`,
...     which is given to ast.parse
...     '''
...     # TODO: improve docstring
...     node = ast.parse(expression)
...     body = node.body
...     return ifilter(lambda node: isinstance(node, ast.FunctionDef), body)
... 
>>> list(yield_functions(file_content.read()))
[<_ast.FunctionDef object at 0x94c8e6c>, <_ast.FunctionDef object at 0x94d2d2c>, <_ast.FunctionDef object at 0x94d2eec>]
theliquidwave
User
Beiträge: 221
Registriert: Sonntag 1. Juni 2008, 09:08

Hi.
Danke, aber das löst mein Problem nicht. Ich brauche das ja in C. Ein PyObject mit einer Liste aller Funktionen würde mir ja schon reichen.

(Nur mal nebenbei, wäre mein Problem in Python, würde ich es so machen: - auch wenn ich für diese Lösung eigentlich gesteinigt gehöre :lol:)

Code: Alles auswählen

>>> import urllib2
>>> basetype = type(lambda: True) # mir ist nichts besseres eingefallen
>>> functions = [x for x in dir(urllib2) if basetype is type(getattr(urllib2, x))]
>>> functions
['_parse_proxy', 'build_opener', 'getproxies', 'install_opener', ...]
Gruß
Grüßle.
derdon
User
Beiträge: 1316
Registriert: Freitag 24. Oktober 2008, 14:32

Anstatt

Code: Alles auswählen

type(lambda: True)
hättest du

Code: Alles auswählen

import types
types.FunctionType
nutzen können. Und ``isinstance(x, y)`` statt ``x is type(y)``.

Aber es soll ja C sein, also halte ich lieber meinen Mund ;)
theliquidwave
User
Beiträge: 221
Registriert: Sonntag 1. Juni 2008, 09:08

Hätte ich

Code: Alles auswählen

import types
types.FunctionType
gekannt, hätte ich das auch getan. Und isinstance funktioniert mit meiner Methode nicht :P

Gruß
Grüßle.
Leonidas
Python-Forum Veteran
Beiträge: 16025
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

Chrisber hat geschrieben:Und isinstance funktioniert mit meiner Methode nicht :P
Inwiefern?

Code: Alles auswählen

[key for (key, value) in urllib2.__dict__.iteritems() if isinstance(value, types.FunctionType)]
My god, it's full of CARs! | Leonidasvoice vs (former) Modvoice
Benutzeravatar
cofi
Python-Forum Veteran
Beiträge: 4432
Registriert: Sonntag 30. März 2008, 04:16
Wohnort: RGFybXN0YWR0

Code: Alles auswählen

>>> import urllib2
>>> basetype = type(lambda: True)
>>> funcs = [x for x in dir(urllib2) if isinstance(x, basetype)]
>>> funcs
[]
Er bezog sich ja auf seine Methode, d.h. mit `type(lambda:True)`.
BlackJack

Code: Alles auswählen

In [149]: import inspect, urllib2

In [150]: inspect.getmembers(urllib2, inspect.isfunction)
Out[150]:
[('_parse_proxy', <function _parse_proxy at 0x8cff144>),
 ('build_opener', <function build_opener at 0x8cfbb54>),
 ('getproxies', <function getproxies_environment at 0x8cfb994>),
 ('install_opener', <function install_opener at 0x8cf20d4>),
 ('localhost', <function localhost at 0x8cf29cc>),
 ('noheaders', <function noheaders at 0x8cfb1ec>),
 ('parse_http_list', <function parse_http_list at 0x8cffaac>),
 ('parse_keqv_list', <function parse_keqv_list at 0x8cff614>),
 ('quote', <function quote at 0x8cfb8ec>),
 ('randombytes', <function randombytes at 0x8cff304>),
 ('request_host', <function request_host at 0x8cf2224>),
 ('splitattr', <function splitattr at 0x8cfb7d4>),
 ('splitgophertype', <function splitgophertype at 0x8cfb844>),
 ('splithost', <function splithost at 0x8cfb64c>),
 ('splitpasswd', <function splitpasswd at 0x8cfb6bc>),
 ('splitport', <function splitport at 0x8cfb6f4>),
 ('splitquery', <function splitquery at 0x8cfb764>),
 ('splittype', <function splittype at 0x8cfb614>),
 ('splituser', <function splituser at 0x8cfb684>),
 ('splitvalue', <function splitvalue at 0x8cfb80c>),
 ('unquote', <function unquote at 0x8cfb87c>),
 ('unwrap', <function unwrap at 0x8cfb5dc>),
 ('url2pathname', <function url2pathname at 0x8cf2844>),
 ('urlopen', <function urlopen at 0x8cf25dc>)]
Und bevor jetzt wieder dieses "ich brauche das aber in C" kommt: Man kann das `inspect`-Modul auch in C importieren und die entsprechenden Funktionen benutzen. Das Modul ist für diesen Zweck da, warum muss man das nochmal erfinden?
derdon
User
Beiträge: 1316
Registriert: Freitag 24. Oktober 2008, 14:32

Ah cool, das inspect-Modul kannte ich noch gar nicht.
Antworten