eyed3 python module

python - eyed3



¿Por qué el valor de__name__ cambia después de la asignación a sys.modules[__ name__]? (2)

Mientras intentaba hacer algo similar a lo que se encuentra en la receta de ActiveState titulada Constantes en Python por Alex Martelli, me encontré con el efecto secundario inesperado (en Python 2.7) que asigna una instancia de clase a una entrada en sys.modules . al hacerlo, aparentemente 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):

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á sucediendo. No creo que fuera así en Python 2.6 y versiones anteriores, ya que tengo un código más antiguo donde aparentemente el if __name__ == ''__main__'': condicional funcionó como se esperaba después de la asignación (pero ya no lo hace).

FWIW, también noté que el nombre _test se está recuperando de un objeto de clase a None , después de la asignación. Me parece extraño que se estén recuperando en None lugar de desaparecer por completo ...

Actualizar:

Me gustaría agregar que cualquier solución para lograr el efecto de if __name__ == ''__main__'': dado lo que sucede, sería muy apreciado. TIA!


Esto sucede porque ha sobrescrito su módulo cuando hizo sys.modules[__name__] = _test() por lo que su módulo se eliminó (porque el módulo ya no tenía ninguna referencia y el contador de referencia se puso a cero, por lo que se eliminó) pero, mientras tanto, el intérprete aún tiene el código de bytes, por lo que seguirá funcionando, pero devolviendo None a todas las variables en su módulo (esto se debe a que Python establece todas las variables en None en un módulo cuando se elimina).

class _test(object): pass import sys print sys.modules[''__main__''] # <module ''__main__'' from ''test.py''> <<< the test.py is the name of this module sys.modules[__name__] = _test() # Which is the same as doing sys.modules[''__main__''] = _test() but wait a # minute isn''t sys.modules[''__main__''] was referencing to this module so # Oops i just overwrite this module entry so this module will be deleted # it''s like if i did: # # import test # __main__ = test # del test # __main__ = _test() # test will be deleted because the only reference for it was __main__ in # that point. print sys, __name__ # None, None import sys # i should re import sys again. print sys.modules[''__main__''] # <__main__._test instance at 0x7f031fcb5488> <<< my new module reference.

EDITAR:

Una solución será haciendo esto:

class _test(object): pass import sys ref = sys.modules[__name__] # Create another reference of this module. sys.modules[__name__] = _test() # Now when it''s overwritten it will not be # deleted because a reference to it still # exists. print __name__, _test # __main__ <class ''__main__._test''>

Espero que esto explique las cosas.


Si asigno algo a sys.modules[''__main__''] obtengo un entorno muy dañado. No es este comportamiento exacto, pero todos mis globales y elementos desaparecen.

no se ha documentado que sys.modules se comporte de ninguna manera en particular cuando se escribe, solo vagamente que puede usarlo para "recargar trucos" (y hay algunas trampas importantes incluso para ese uso).

No le escribiría un no-módulo y no esperaría más que dolor. Creo que esta receta está totalmente equivocada.