2014-12-22 3 views
1

У меня есть система тестирования модуля в Python, где отдельные модули называют что-то вроде:Найти переменные, определенные в другом модуле (питон)

class Hello(object): 
    _DOC_ATTR = { 'greeting': ''' 
     a greeting message. 

     >>> h = Hello() 
     >>> h.greeting = 'hi there' 
     >>> h.greeting 
     'hi there' 
     ''' } 

    def __init__(self): 
     self.greeting = "hello" 

class Test(unittest.TestCase): 
    # tests here 

if __name__ == '__main__': 
    import tester 
    tester.test(Test) 

внутри mainTest, я бегу тестов в тесте вместе с doctest на "__main__". Это отлично работает и отлично работает долгое время. Наш специализированный словарь _DOC_ATTR документирует отдельные атрибуты функции при создании в Sphinx. Однако доктрины в этом словаре не называются. То, что я хотел бы сделать, находится в пределах tester.test(), чтобы запустить доктрины в значениях в _DOC_ATTR каждого класса.

Проблема, с которой я столкнулась, заключается в том, чтобы найти способ в пределах tester.test(), чтобы выяснить все переменные (в частности классы), определенные в __main__. Я пробовал смотреть на соответствующие места в traceback безрезультатно. Я думал, что, поскольку я проходил в классе от __main__, а именно __main__.Test, я мог бы использовать .__module__ от Test, чтобы получить доступ к локальным переменным там, но я не могу понять, как это сделать.

Мне не нужно менять звонок на tester.test(Test), так как он используется в сотнях модулей, и я обучил всех программистов, работающих над проектом, следовать этой парадигме. Спасибо за любую помощь!

ответ

0

Я думаю, что я, возможно, нашли ответ:

import inspect 
    stacks = inspect.stack() 
    if len(stacks) > 1: 
     outerFrame = stacks[1][0] 
    else: 
     outerFrame = stacks[0][0] 
    localVariables = outerFrame.f_locals 
    for lv in list(localVariables.keys()): 
     lvk = localVariables[lv] 
     if (inspect.isclass(lvk)): 
      docattr = getattr(lvk, '_DOC_ATTR', None) 
      if docattr is not None: 
       # ... do something with docattr ... 

Другое решение: поскольку мы передаем класс «Test» в, и для того, чтобы запустить там должна быть функция «RunTest» определен , можно также использовать func_globals для этой функции. Обратите внимание, что это не может быть функция, унаследованная от суперкласса, например __init__, поэтому она может иметь ограниченную функциональность для более широких случаев использования.

import inspect 
    localVariables = Test.runTest.func_globals 
    for lv in list(localVariables.keys()): 
     lvk = localVariables[lv] 
     if (inspect.isclass(lvk)): 
       #### etc.  
Смежные вопросы