I'm trying to create an import statement that's pluggable with other projects. This statement is located in urls.py
So this works:
from forum.urls import urlpatterns # Base Class: <type 'list'>
But this doesn't work:
from settings import ROOT_URLCONF as project_urls urlpatterns = __import__(project_urls) # Base Class: <type 'module'>
How can I get the latter to work?
urlpatterns = __import__(project_urls).whateversubmodule.urlpatterns
So you want to have import statements that are relative to earlier imports?
Definitely something I tried at one point. I had some very long import statements that had a common root, so I tried to factor it out. I could not get it to work with straight import statements, but maybe I didn't try hard enough.
Keep in mind that the import statement behavior by default is going to create a module object. It will then bind it into sys.modules, and then bind it in your current module's namespace with the name from the import statement. See http://docs.python.org/tutorial/modules.html.
A module object has a namespace. If a module is not a package, it's namespace comes from evaluating the contents of the .py file of the module. However, if it is a package then the namespace comes from the
__init__.py module in the package. The other modules in the package are not imported automatically and are not available in the package's namespace. You have to import them separately.
The from...import statement will load the module into sys.modules. Then it will pull the object out of that module to which you referred in the import. Finally it binds that object into your current module's namespace with the name from the import statement. Basically you are copying a binding from one namespace to another. To be honest I find that it usually obfuscates the source of the name when you use it later (so I don't do it much).
To the point:
Your use of
__import__ is one way around the limits of the import statement. See the python documentation. However, if you use a from..import statement don't try to reuse the resulting name in
__import__ unless that is pointing to a module object (which it probably isn't). Imports need a dot-delimited sequence of module names only.
As well, keep in mind that just putting the explicit import may be a cleaner way to indicate where an object came from.