Python — фрагмент кода не работает на Python 2.5.6 с использованием IDLE

Я использую часть самомодифицирующегося кода для проекта колледжа.

Вот:

import datetime
import inspect
import re
import sys

def main():
    # print the time it is last run
    lastrun = 'Mon Jun  8 16:31:27 2009'

    print "This program was last run at ",
    print lastrun

    # read in the source code of itself
    srcfile = inspect.getsourcefile(sys.modules[__name__])
    f = open(srcfile, 'r')
    src = f.read()
    f.close()

    # modify the embedded timestamp
    timestamp = datetime.datetime.ctime(datetime.datetime.now())
    match = re.search("lastrun = '(.*)'", src)
    if match:
        src = src[:match.start(1)] + timestamp + src[match.end(1):]

    # write the source code back
    f = open(srcfile, 'w')
    f.write(src)
    f.close()

if __name__=='__main__':
    main()

К сожалению, это не работает. Ошибка возвращена:

# This is the script's output
This program is last run at  Mon Jun  8 16:31:27 2009
# This is the error message
Traceback (most recent call last):
  File "C:\Users\Rui Gomes\Desktop\teste.py", line 30, in <module>
    main()
  File "C:\Users\Rui Gomes\Desktop\teste.py", line 13, in main
    srcfile = inspect.getsourcefile(sys.modules[__name__])
  File "C:\Python31\lib\inspect.py", line 439, in getsourcefile
    filename = getfile(object)
  File "C:\Python31\lib\inspect.py", line 401, in getfile
    raise TypeError('{!r} is a built-in module'.format(object))
TypeError: <module '__main__' (built-in)> is a built-in module

Буду признателен за любые решения.


person F. P.    schedule 02.06.2010    source источник
comment
Самомодифицирующийся код — это зло. На любом языке.   -  person Ignacio Vazquez-Abrams    schedule 02.06.2010
comment
Проверьте свой путь, вы вызываете ресурсы \Python31\lib из IDLE 2.5.6?   -  person Don    schedule 02.06.2010
comment
Вау, это плохая идея. Почему время выполнения нельзя записать где-то еще?   -  person S.Lott    schedule 02.06.2010
comment
Это просто доказательство концепции. Академическое любопытство.   -  person F. P.    schedule 02.06.2010
comment
И было трудно отлаживать. Какие еще доказательства вам нужны, что это плохая идея?   -  person S.Lott    schedule 02.06.2010
comment
Я понимаю, что это плохая идея, и я бы никогда не сделал этого в реальном проекте, но мне было любопытно посмотреть, смогу ли я заставить это работать должным образом.   -  person F. P.    schedule 03.06.2010
comment
@Fancisco P.: Это распространенный вариант использования. Очень распространен. И никто не использует для этого самомодифицирующийся код. Они используют файлы. Часто в каталогах /var/log или /var/run. Любопытство должно, возможно, иметь пределы, определяемые практичностью.   -  person S.Lott    schedule 03.06.2010


Ответы (2)


Он прекрасно работает вне IDLE, поэтому проблема не только в вашем коде, но и в среде, в которой вы его выполняете. Когда вы запускаете ошибочную часть своего кода в IDLE, вы получаете следующий вывод:

>>> import inspect
>>> sys.modules[__name__]
<module '__main__' from 'C:\Python26\Lib\idlelib\idle.pyw'>
>>> inspect.getsourcefile(sys.modules[__name__])
'C:\\Python26\\Lib\\idlelib\\idle.pyw'

Когда вы запускаете это в IDLE

# read in the source code of itself
srcfile = inspect.getsourcefile(sys.modules[__name__])
f = open(srcfile, 'r')
src = f.read()
f.close()

вы на самом деле пытаетесь изменить 'C:\\Python26\\Lib\\idlelib\\idle.pyw' ... что IDLE не позволит вам сделать.

Короче говоря, то, что вы написали, действительно работает, но его нельзя запустить в IDLE.

person Sean Vieira    schedule 02.06.2010
comment
Проблема не связана с частью openfile, поскольку исключение запускается в inspect.getsourcefile(sys.modules[name]) - person joaquin; 02.06.2010

Вы можете использовать глобальный атрибут __file__, чтобы получить исходный путь текущего модуля.

Из документов 2.6:

__file__ — это путь к файлу, из которого был загружен модуль, если он был загружен из файла. Атрибут __file__ отсутствует для модулей C, которые статически связаны с интерпретатором; для модулей расширения, загружаемых динамически из общей библиотеки, это путь к файлу общей библиотеки.

РЕДАКТИРОВАТЬ:

Я сделал предположение, что inspect.getsourcefile() всегда будет выдавать TypeError при проверке модуля __main__. Это только в случае запуска из интерактивного интерпретатора. Я исправляюсь. Дерп.

person Jeremy Brown    schedule 02.06.2010