Cuando se usa __import__
con un nombre punteado, algo así como: somepackage.somemodule
, el módulo devuelto no es somemodule
, ¡lo que se devuelve parece estar casi vacío! ¿Que está pasando aqui?__import__ de Python no funciona como se esperaba
Respuesta
A partir de los documentos de pitón en __import__
:
__import__(name[, globals[, locals[, fromlist[, level]]]])
...
Cuando la variable es el nombre de la package.module forma , normalmente, el paquete de nivel superior (la nombre hasta el primer punto) se devuelve, no el módulo nombrado por nombre. Sin embargo, cuando se proporciona un argumento de lista no vacío, se devuelve el módulo nombrado por nombre. Esto se hace para la compatibilidad con el bytecode generado para el diferentes tipos de instrucción de importación; al usar "import spam.ham.eggs", el paquete de nivel superior se debe colocar en el espacio de nombre de importación, pero cuando usando "from spam.ham import eggs", se debe usar el subpaquete spam.ham a encuentra los huevos variables. Como una solución alternativa para este comportamiento, use getattr() para extraer los componentes deseados. Por ejemplo, se puede definir la siguiente ayudante:
def my_import(name): mod = __import__(name) components = name.split('.') for comp in components[1:]: mod = getattr(mod, comp) return mod
Parafraseando:
Cuando pide somepackage.somemodule
, __import__
vuelve somepackage.__init__.py
, lo cual es a menudo vacío.
Se volverá somemodule
si proporciona fromlist
(una lista de los nombres de las variables somemodule
que desee, que no se devuelven en realidad)
También puede, como lo hice, utilice la función que sugieren.
Nota: Hice esta pregunta totalmente con la intención de responderla yo mismo. Hubo un gran error en mi código, y después de haberlo diagnosticado mal, me tomó mucho tiempo resolverlo, así que pensé que ayudaría a la comunidad SO y publicaría el gotcha con el que me encontré aquí.
Hay algo que funcione como usted quiere que: twisted.python.reflect.namedAny
:
>>> from twisted.python.reflect import namedAny
>>> namedAny("operator.eq")
<built-in function eq>
>>> namedAny("pysqlite2.dbapi2.connect")
<built-in function connect>
>>> namedAny("os")
<module 'os' from '/usr/lib/python2.5/os.pyc'>
Python 2.7 tiene importlib, caminos de puntos se resuelven como se esperaba
import importlib
foo = importlib.import_module('a.dotted.path')
instance = foo.SomeClass()
También hay un paquete Python 2.6 que respalda esta funcionalidad. https://pypi.python.org/pypi/importlib/ – melinath
para Python 2.6, he escrito este fragmento:
def import_and_get_mod(str, parent_mod=None):
"""Attempts to import the supplied string as a module.
Returns the module that was imported."""
mods = str.split('.')
child_mod_str = '.'.join(mods[1:])
if parent_mod is None:
if len(mods) > 1:
#First time this function is called; import the module
#__import__() will only return the top level module
return import_and_get_mod(child_mod_str, __import__(str))
else:
return __import__(str)
else:
mod = getattr(parent_mod, mods[0])
if len(mods) > 1:
#We're not yet at the intended module; drill down
return import_and_get_mod(child_mod_str, mod)
else:
return mod
Existe una solución más simple, como se explica en la documentación:
Si simplemente desea importar un módulo (potencialmente dentro de un paquete) por nombre, puede llamar a __import __() y luego buscarlo en el sistema.módulos:
>>> import sys
>>> name = 'foo.bar.baz'
>>> __import__(name)
<module 'foo' from ...>
>>> baz = sys.modules[name]
>>> baz
<module 'foo.bar.baz' from ...>
La forma en que lo hice es
foo = __import__('foo', globals(), locals(), ["bar"], -1)
foobar = eval("foo.bar")
entonces puedo acceder a cualquier contenido de por
foobar.functionName()
¿Por qué no simplemente 'foo.bar' en ese punto? –
- 1. Python .sort() no funciona como se esperaba
- 2. El cierre de Python no funciona como se esperaba
- 3. os.path.isfile no funciona como se esperaba
- 4. de accesibilidad no funciona como se esperaba
- 5. consulta SQL no funciona como se esperaba
- 6. __pospostback no funciona como se esperaba
- 7. Autowiring Map no funciona como se esperaba
- 8. : first-child no funciona como se esperaba
- 9. ToDictionary no funciona como se esperaba
- 10. PHP is_int no funciona como se esperaba
- 11. SmartGit pull no funciona como se esperaba
- 12. Combobox SelectedItem no funciona como se esperaba
- 13. TagBuilder.MergeAttributes no funciona como se esperaba
- 14. Time.use_zone no funciona como se esperaba
- 15. C# Destructor no funciona como se esperaba
- 16. java.util.BitSet - set() no funciona como se esperaba
- 17. android: layout_gravity no funciona como se esperaba
- 18. DateTime.AddDays() no funciona como se esperaba
- 19. TransiciónDibujado como fondo en TextView no funciona como se esperaba
- 20. Cadenas de concatenación no funciona como se esperaba
- 21. CompileTimeChecker de Modern C++ Design no funciona como se esperaba
- 22. La alineación vertical de JLabel no funciona como se esperaba
- 23. Re-group de Django no funciona como se esperaba
- 24. Parche de fecha y hora no funciona como se esperaba
- 25. Altura de ventana = "Auto" no funciona como se esperaba
- 26. Backbone JS Routing no funciona como esperaba
- 27. jQuery fadeOut/fadeIn no funciona como se esperaba?
- 28. IIS 404 Error personalizado no funciona como se esperaba
- 29. La función jquery add no funciona como se esperaba
- 30. La transacción SQLite no funciona como se esperaba
que es muy útil, sin embargo yo realmente no tengo ninguna otra necesidad de retorcido en mi programa. Aunque, como fundador (!), Probablemente conozcas más las posibilidades que yo (nunca lo usaste). – dwestbrook