2012-01-25 30 views
4

我想创建一个帮助函数来读取文件并模拟出单元测试的所有导入。我不得不读取文件与导入,因为我没有这些东西在python路径。Python简单的方法来读取py模块中的所有导入语句

示例代码:


#module.py 
import com.stackoverflow.question 
from com.stackoverflow.util import test_func 
from com.stackoverflow.util import TestClass 

#magic helper: what i want 
magic = process('<path_to>/module.py') 
for module in magic.modules_as_strings(): 
    #todo would have to recuirsively add each path 
    # so i would first create com, then com.stackoverflow, etc 
    setattr(self, module, StubModules(module) 
for obj in magic.sink: 
    #these would be "from" from x import Y 
    #its basically just creating self.Y = object 
    setattr(self, object) 

以上是模拟代码,我真的找最好的办法只有记号化的 “从/ import语句”

文件

这有道理吗?我知道我可以逐行读取文件,但我希望能够采用更简洁,更简洁的方式。

让我知道如果您有任何问题。

+0

您可以加入一个例子输出魔法调用(数据结构)? – GaretJax

+0

对不起,我错过了这一点,但我只是期待字符串完全限定的模块,所以像a.b.c.module_name。我正要标记它.. – Nix

+0

我希望我的解决方案也能工作。你总是可以去掉不必要的部分。 – GaretJax

回答

9

使用AST模块,这是很简单的:

import ast 
from collections import namedtuple 

Import = namedtuple("Import", ["module", "name", "alias"]) 

def get_imports(path): 
    with open(path) as fh:   
     root = ast.parse(fh.read(), path) 

    for node in ast.iter_child_nodes(root): 
     if isinstance(node, ast.Import): 
      module = [] 
     elif isinstance(node, ast.ImportFrom): 
      module = node.module.split('.') 
     else: 
      continue 

     for n in node.names: 
      yield Import(module, n.name.split('.'), n.asname) 

对于这样一个模块:

from coco import bunny 
from coco.bungy import carrot 
from meta import teta 
from rocket import spaceship as sp 
import bingo 
import com.stackoverflow 
import motorbike as car 
import module1, module2 

s="a random variable" 

def func(): 
    """And a function""" 

输出是:

>>> for imp in get_imports("/path/to/file.py"): print imp 
Import(module=['coco'], name=['bunny'], alias=None) 
Import(module=['coco', 'bungy'], name=['carrot'], alias=None) 
Import(module=['meta'], name=['teta'], alias=None) 
Import(module=['rocket'], name=['spaceship'], alias='sp') 
Import(module=[], name=['bingo'], alias=None) 
Import(module=[], name=['com', 'stackoverflow'], alias=None) 
Import(module=[], name=['motorbike'], alias='car') 
Import(module=[], name=['module1'], alias=None) 
Import(module=[], name=['module2'], alias=None) 
+0

嗯。我81秒击败你,但你更漂亮。 +1。 – DSM

+0

谢谢! ;-)我正在等待OP的回复,并最终放弃了,当我看到你已经回复了...:-P – GaretJax

+0

这是完美的......谢谢! – Nix

相关问题