Ben
Ben

Reputation: 5414

How to import modules that import other modules without using import *

Inside the parent class basehandler.py, there are several import statements, a constant, and a class:

import os
import sys
import cgi
import json

JINJA_ENVIRONMENT = jinja2.Environment(foobar)

class BaseHandler(webapp2.RequestHandler):
    pass

Another module, main.py then imports this parent module with from basehandler import *

If we use from basehandler import BaseHandler or import basehandler so as to avoid the from foo import * statement, then the modules that the parent class imports are not received and the program throws an exception.

How do I avoid from foo import * while still correctly importing the parent module with the modules that it imports?

Upvotes: 2

Views: 170

Answers (3)

jfs
jfs

Reputation: 414129

then the modules that the parent class imports are not received and the program throws an exception.

If your program uses a module then you should import it in the module itself, not in some other module e.g., use import os in your program instead of from foo import * where foo module imports os inside.


To answer the question in the title: to make all imported modules from another module available without a wild-card import:

import inspect 
import foo # your other module

# get all modules from `foo` and make the names available
globals().update(inspect.getmembers(foo, inspect.ismodule)) #XXX don't do it

It is like from foo import * that imports only modules. The same warnings against wild-card imports are applicable here.

Upvotes: 1

jsbueno
jsbueno

Reputation: 110208

I say there is something else wrong there - Importing your "basehandler" module from elsewhere should just work: the names, modules, classes and objects it needs are bound to its own namespace, and are present in the globals dictionary of any code defined in that module - regardless of you getting it with a from basehandler import BaseHandler statement.

Please, post your full traceback so that people can find out what is actually happening there.

Upvotes: 0

Moritz
Moritz

Reputation: 4761

Referencing this answer, you can define a function in basehandler.py that yields all imported modules:

import os,sys,cgi,json
import types

def get_imports():
    for name, val in globals().items():
        if isinstance(val, types.ModuleType):
            yield val.__name__

...and then import that function in main.py and use exec to import the relevant modules:

from basehandler import BaseHandler, get_imports

for i in get_imports():
    exec "import %s" % i

print os.getcwd() #this will work

Sort of a gnarly way of doing it though, is there a specific reason you're not just re-importing the list of modules in main.py?

Upvotes: 1

Related Questions