开发者

Python - Code snippet not working on Python 2.5.6, using IDLE

I am using a piece of self-modifying code for a college project.

Here it 开发者_如何学编程is:

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()

Unfortunately, it doesn't work. Error returned:

# 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

I'd be thankful for any solutions.


It runs perfectly when run outside of IDLE -- so therefore the problem is not in your code alone, but in the environment where you are executing it. When you run the erroring portion of your code in IDLE you get this output:

>>> 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'

When you run this in IDLE

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

you are actually trying to modify 'C:\\Python26\\Lib\\idlelib\\idle.pyw' ... which IDLE will not let you do.

The long and the short of it seems to be that what you have written does work: but it cannot be run in IDLE.


You could use the __file__ global attribute to get the current module's source path.

From the 2.6 docs:

__file__ is the pathname of the file from which the module was loaded, if it was loaded from a file. The __file__ attribute is not present for C modules that are statically linked into the interpreter; for extension modules loaded dynamically from a shared library, it is the pathname of the shared library file.

EDIT:

I made the assumption that inspect.getsourcefile() would always throw TypeError when inspecting the __main__ module. That's only the case when run from an interactive interpreter. I stand corrected. Derp.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜