"Leif K-Brooks" <[EMAIL PROTECTED]> > In Python 2.4, although None can't be directly assigned to, > globals()['None'] can still be; however, that won't change the value of > the expression "None" in ordinary statements. Except with the eval > function, it seems: > > Python 2.4 (#2, Dec 3 2004, 17:59:05) > [GCC 3.3.5 (Debian 1:3.3.5-2)] on linux2 > Type "help", "copyright", "credits" or "license" for more information. > >>> print None > None > >>> print eval('None') > None > >>> globals()['None'] = "spam" > >>> print None > None > >>> print eval('None') > spam > > I don't really mind this weird behavior; I'm just curious about it. Does > anyone know what might be going on in Python's internals to cause the > difference between "print None" and "print eval('None')"?
It is a nuance of how None is being made constant. For backwards compatability, None still has to be in the globals dictionary. Like all entries in the globals dictionary, you can change it if you try hard enough (which you did). For Py2.4, whenever bytecode is generated for a code object, references to "None" in the globals dictionary are bypassed and replaced with a constant reference to Py_None, the one, true, singleton instance of None. That will occur even if you've mucked with None entry in the globals dictionary. Bytecode for eval() doesn't go through the bytecode optimizer so its dictionary lookup is retained (producing the effect in your example). To have made None a literal constant would have been a much more radical step. Py2.4 simulates this and gives you the real benefit being sought, faster function execution, without having incurred the costs of having a new literal. It's possible to fool the simulation, but who cares. Raymond Hettinger -- http://mail.python.org/mailman/listinfo/python-list