Al intentar hacer algo similar a lo que contiene la receta ActiveState titulada Constants in Python por Alex Martelli, encontré el inesperado efecto secundario (en Python 2.7) que tiene la asignación de una instancia de clase a una entrada en sys.modules
, es decir que hacerlo al parecer, cambia el valor de __name__
a None
como se ilustra en el siguiente fragmento de código (que rompe parte del código en la receta):¿Por qué cambia el valor de __name__ después de la asignación a sys.modules [__ name__]?
class _test(object): pass
import sys
print '# __name__: %r' % __name__
# __name__: '__main__'
sys.modules[__name__] = _test()
print '# __name__: %r' % __name__
# __name__: None
if __name__ == '__main__': # never executes...
import test
print "done"
me gustaría entender por qué esto está ocurriendo. No creo que fuera así en Python 2.6 y versiones anteriores, ya que tengo un código anterior donde aparentemente el condicional if __name__ == '__main__':
funcionó como se esperaba después de la asignación (pero ya no funciona).
FWIW, también noté que el nombre _test
está recibiendo rebote de un objeto de clase a None
, también, después de la asignación. Parece extraño para mí que están siendo rebote a None
en vez de desaparecer por completo ...
Actualización:
me gustaría añadir que soluciones provisionales para lograr el efecto de if __name__ == '__main__':
, teniendo en cuenta lo suceder sería muy apreciado. TIA!
Y el comportamiento "sobrescribir todo con ninguno" proviene de algo que el destructor del módulo hace deliberadamente para borrar los ciclos de referencia entre las funciones definidas en el módulo y el módulo '__dict__'. – ncoghlan
Buena respuesta y excelente solución. Nunca había considerado eso eliminar un 'sys.La referencia de módulos [] 'al módulo podría provocar su destrucción inmediata debido a que su recuento de referencias se iría a cero (especialmente si se tiene en cuenta que se está haciendo mediante código en el propio módulo). ¡Gracias! – martineau
En función de su sugerencia de solución alternativa, he reemplazado el 'sys.modules [__ name__] = _test()' con un '_ref, sys.modules [__ name__] = sys.modules [__ name__], _test()' y todo parece bueno otra vez. – martineau