удаление файлов py и сохранение файлов pyc нарушает код проверки

#python #bytecode #inspect

#python #байт-код #Осмотр

Вопрос:

Приведенная ниже функция работает просто отлично. Но если я удалю все py файлы (и оставлю pyc их нетронутыми), я получу сообщение об ошибке:

Чтобы объяснить, что я подразумеваю под «неповрежденным», вот более или менее то, что я сделал: 1. напишите кучу файлов py и поместите их в понятную структуру каталогов 2. протестируйте код кода. Это работает 3. скомпилируйте все файлы py, чтобы получить файлы pyc 4. удалите файлы py 5. протестируйте код. Сбой

Функция:

 def get_module_name_and_line():
    """
    return the name of the module from which the method calling this method was called.
    """
    import inspect
    lStack = inspect.stack()
    oStk = lStack[2]
    oMod = inspect.getmodule(oStk[0])         
    oInfo = inspect.getframeinfo(oStk[0])
    sName = oMod.__name__    #<<<<<<<<<<<<<<<<<< ERROR HERE
    iLine = oInfo.lineno
    return sName,iLine 
 

Ошибка:

 AttributeError: 'NoneType' object has no attribute '__name__'
 

Так oMod None и в этой ошибке. Если файлы py находятся рядом, то oMod никогда None .

Вопрос:

Почему inspect возвращает модуль только в том случае, если файлы py не повреждены? Как я могу заставить эту функцию работать без файлов py.

Полная трассировка:

 Original exception was:
Traceback (most recent call last):
File "/home/criticalid/programs/damn.py", line 630, in <module>
File "/home/criticalid/programs/golly/class_foo.py", line 121, in moo
File "/home/criticalid/programs/golly/class_foo.py", line 151, in get_module_name_and_line
AttributeError: 'NoneType' object has no attribute '__name__'
 

Комментарии:

1. Я не уверен, что вы подразумеваете под «файлами py нетронутыми». В этом коде, я думаю, вы могли бы попробовать sname = oMod.__name if oMod else 'Unknown Name' то же самое для iLINE. Таким образом, ваш метод, по крайней мере, вернет

2. @RobertEkendahl: неповрежденный означает не удаленный. Если у меня есть файлы py, все работает. Если у меня есть только файлы pyc, то он ломается

3. @Sheena: верно, без .py исходных файлов трассировка намного … реже. Это дает понять, что ваше исключение не в getmodule() вызове, а только в том, что возвращается None .

4. @MartijnPieters: точно. Но я не знаю, почему он возвращается None . Функция вызывается точно так же, единственное отличие — отсутствие файлов py. Может ли быть так, что модулю inpect нужны файлы py для правильной работы? Я предположил, что удаление файлов py не будет иметь значения, потому что байт-код будет точно таким же в любом случае.

5. Вы пробовали не удалять свой исходный код? .pyc-файлы представляют собой недокументированную деталь реализации.

Ответ №1:

Это работает для меня. Предполагается, что все модули находятся в пакетах в текущем рабочем каталоге. И он возвращает не __main__ модуль, а его имя файла.

Я уверен, что есть лучшее решение, но это решает мои проблемы.

 def get_module_name_and_line():
    """
    return the name of the module from which the method calling this method was called.
    """
    def get_name_from_path(sPath):
        import os
        sCWD = os.getcwd()
        lCWD = list(os.path.split(sCWD))
        lPath = list(os.path.split(sPath))
        lPath[-1] = '.'.join(lPath[-1].split('.')[:-1])   #remove file extension
        lRet = [s for s in lPath[len(lCWD)-1:]]
        return '.'.join(lRet)

    import inspect
    lStack = inspect.stack()
    oStk = lStack[2]
    iLine = inspect.getlineno(oStk[0])
    sName = get_name_from_path(inspect.getfile(oStk[0]))
    return sName,iLine