2010-06-02 15 views
3

J'utilise un morceau de code auto-modifiable pour un projet de collège.Python - extrait de code ne fonctionne pas sur Python 2.5.6, en utilisant IDLE

Ici, il est:

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

Malheureusement, cela ne fonctionne pas. Erreur renvoyée:

# 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 

Je serais reconnaissant pour toutes les solutions.

+2

Le code auto-modifiable est mauvais. Dans n'importe quelle langue. –

+3

Vérifiez votre chemin, vous appelez \ Python31 \ lib ressources de IDLE 2.5.6? – Don

+0

Wow c'est une mauvaise idée. Pourquoi l'exécution ne peut-elle pas être enregistrée ailleurs? –

Répondre

4

Il fonctionne parfaitement lorsqu'il est exécuté en dehors de IDLE - donc le problème n'est pas uniquement dans votre code, mais dans l'environnement où vous l'exécutez. Lorsque vous exécutez la partie erroring de votre code IDLE vous obtenez cette sortie:

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

Lorsque vous exécutez cette dans IDLE

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

vous en train d'essayer de modifier 'C:\\Python26\\Lib\\idlelib\\idle.pyw' ... qui IDLE Je ne te laisserai pas faire.

Le long et le court de ce semble être que ce que vous avez écrit fonctionne: mais il ne peut pas être exécuté dans IDLE.

+1

Le problème n'est pas lié à la partie openfile car l'exception est déclenchée dans inspect.getsourcefile (sys.modules [__ name__]) – joaquin

+0

Merci, corrigez-le. –

3

Vous pouvez utiliser l'attribut global pour obtenir le chemin source du module en cours.

Des docs 2.6:

__file__ est le chemin du fichier à partir duquel le module a été chargé, si il a été chargé à partir d'un fichier. L'attribut __file__ n'est pas présent pour les modules C qui sont liés statiquement dans l'interpréteur; Pour les modules chargés dynamiquement à partir d'une bibliothèque partagée , il s'agit du chemin d'accès du fichier de bibliothèque partagée .

EDIT:

J'ai fait l'hypothèse que inspect.getsourcefile() serait toujours jeter TypeError lors de l'inspection du module __main__. C'est seulement le cas lorsqu'il est exécuté à partir d'un interpréteur interactif. Je me suis trompé. Derp.