Detecting imported objects
Given the source code of a Python file, I would like to detect all imported objects. For example, given this source:
import mymod
from mymod2 import obj1, obj2, obj3
from mymod3 import aobj
I want to get:
[('mymod2', 'obj1', 'obj2', 'obj3'), ('mymod3', 'aobj')]
I have already tried this regex:
r'from (?P<mod>[_\w\d]+) import (?:开发者_如何学C(?P<obj>[_\w\d]+)[,\s]?)+'
But I only get the first imported object:
[('mymod2', 'obj1'), ('mymod3', 'aobj')]
A better tool than regular expressions is the ast
module that comes with Python. To find all from ... import
statements in the outermost scope of a.py
and print all imported names, you could use
import ast
code = open("a.py").read()
for node in ast.parse(code).body:
if isinstance(node, ast.ImportFrom):
for name in node.names:
print name.name
Note that this simple code will miss any statements that are not directly at module level, such as import statements inside a try-block. This can easily be fixed by using ast.walk()
to walk over all nodes.
It's a bad idea to textually process the Python source using regexes. A better idea (without dependencies) is to include it in your script, then introspect using Python:
#-- test.py (the file you're targeting)
from time import asctime
from re import match, search
#-- now to find its imports
>>> import test
>>> for imprt in dir(test):
... imprt = getattr(test, imprt, None)
... if not getattr(imprt, '__module__', None):
... continue
... if imprt.__module__ in result:
... result[imprt.__module__].append(imprt.__name__)
... else:
... result[imprt.__module__] = [imprt.__name__]
...
>>> result
{'re': ['match', 'search'], 'time': ['asctime']}
精彩评论