2012-01-25 31 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

相關問題