En utilisant l'espace de nom de premier niveau, c'est impossible. Lorsque vous exécutez
var = 1
Il stocke la clé var
et la valeur 1
dans le dictionnaire global. C'est à peu près équivalent à appeler globals().__setitem__('var', 1)
. Le problème est que vous ne pouvez pas remplacer le dictionnaire global dans un script en cours d'exécution (vous pouvez probablement le faire en jouant avec la pile, mais ce n'est pas une bonne idée). Cependant, vous pouvez exécuter du code dans un espace de nom secondaire, et fournir un dictionnaire personnalisé pour ses globaux.
class myglobals(dict):
def __setitem__(self, key, value):
if key=='val':
raise TypeError()
dict.__setitem__(self, key, value)
myg = myglobals()
dict.__setitem__(myg, 'val', 'protected')
import code
code.InteractiveConsole(locals=myg).interact()
Cela va lancer un REPL qui fonctionne presque normalement, mais qui refuse toute tentative de définir la variable val
. Vous pouvez également utiliser execfile(filename, myg)
. Notez que cela ne protège pas contre les codes malveillants.