Seite 1 von 1
[C API] Durch alle Funktionen iterieren
Verfasst: Montag 11. Januar 2010, 15:26
von theliquidwave
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ß
Verfasst: Montag 11. Januar 2010, 16:01
von derdon
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>]
Verfasst: Montag 11. Januar 2010, 16:12
von theliquidwave
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

)
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ß
Verfasst: Montag 11. Januar 2010, 16:17
von derdon
Anstatt
hättest du
nutzen können. Und ``isinstance(x, y)`` statt ``x is type(y)``.
Aber es soll ja C sein, also halte ich lieber meinen Mund

Verfasst: Montag 11. Januar 2010, 16:48
von theliquidwave
Hätte ich
gekannt, hätte ich das auch getan. Und isinstance funktioniert mit meiner Methode nicht
Gruß
Verfasst: Montag 11. Januar 2010, 17:46
von Leonidas
Chrisber hat geschrieben:Und isinstance funktioniert mit meiner Methode nicht
Inwiefern?
Code: Alles auswählen
[key for (key, value) in urllib2.__dict__.iteritems() if isinstance(value, types.FunctionType)]
Verfasst: Montag 11. Januar 2010, 17:55
von cofi
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)`.
Verfasst: Montag 11. Januar 2010, 19:25
von 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?
Verfasst: Montag 11. Januar 2010, 20:14
von derdon
Ah cool, das inspect-Modul kannte ich noch gar nicht.