views:

240

answers:

6

I have something like this:

 # a.py  
 import os
 class A:
   ...

 # b.py
 import a
 class B(A):
   ...

In class B (b.py) I'd like to be able to use the modules imported in a.py (os in this case). Is it possible to achieve this behavior in Python or should I import the modules in both files?

Edit: I'm not worried about the import times, my problem is the visual clutter that the block of imports puts on the files. I end up having stuff like this in every controller (RequestHandler):

 from django.utils import simplejson
 from google.appengine.ext import webapp
 from google.appengine.ext.webapp import template
 from google.appengine.ext import db

That's what I'd like to avoid.

A: 

You should import it separately. However, if you really need to forward some functionality, you can return a module from a function. Just:

import os
def x:
   return os

But it seems like a plugin functionality - objects + inheritance would solve that case a bit better.

viraptor
I fail how to see the inheritance part here would help. If A is the superclass of B and they both have methods that need the same module for different purposes then I'd have to end up importing that module in the both files, or at least that's what I'm understanding of the current answers.
Federico Builes
What I meant is -> I'm not sure what you want to use the loaded modules for, but the question seems strange. If you get information that module X imports modules Y,Z, then you gain no special information. Why would you care about it at runtime? Usually you will care about some specific functionality that is encapsulated in a function / class that is in the module X itself. Anyway, without specifying why you were asking the question, it's hard to answer with anything better...
viraptor
A: 

Sounds like you are wanting to use python packages. Look into those.

Tom Leys
+1  A: 

Just import the modules again.

Importing a module in python is a very lightweight operation. The first time you import a module, python will load the module and execute the code in it. On any subsequent imports, you will just get a reference to the already-imported module.

You can verify this yourself, if you like:

# module_a.py
class A(object):
    pass

print 'A imported'

# module_b.py
import module_a

class B(object):
    pass

print 'B imported'

# at the interactive prompt
>>> import module_a
A imported
>>> import module_a     # notice nothing prints out this time
>>> import module_b     # notice we get the print from B, but not from A
B imported
>>>
John Fouhy
Working with Google App Engine I end up with 5-6 imports per RequestHandler (controller) so I'd like to avoid that if possible, it's too much clutter in the header of every file.
Federico Builes
A: 

Yep. Once you import a module, that module becomes a property of the current module.

# a.py
class A(object):
    ...

# b.py
import a
class B(a.A):
    ...

In Django, for example, many of the packages simply import the contents of other modules. Classes and functions are defined in separate files just for the separation:

# django/db/models/fields/__init__.py
class Field(object):
    ...
class TextField(Field):
    ...

# django/db/models/__init__.py
from django.db.models.fields import *

# mydjangoproject/myapp/models.py
from django.db import models
class MyModel(models.Model):
    myfield = models.TextField(...)
    ....
a paid nerd
+13  A: 

Yes you can use the imports from the other file by going a.os.

However, the pythonic way is to just import the exact modules you need without making a chain out of it (which can lead to circular references).

When you import a module, the code is compiled and inserted into a dictionary of names -> module objects. The dictionary is located at sys.modules.

import sys
sys.modules

>>> pprint.pprint(sys.modules)
{'UserDict': <module 'UserDict' from 'C:\python26\lib\UserDict.pyc'>,
 '__builtin__': <module '__builtin__' (built-in)>,
 '__main__': <module '__main__' (built-in)>,
 '_abcoll': <module '_abcoll' from 'C:\python26\lib\_abcoll.pyc'>,
# the rest omitted for brevity

When you try to import the module again, Python will check the dictionary to see if its already there. If it is, it will return the already compiled module object to you. Otherwise, it will compile the code, and insert it in sys.modules.

Since dictionaries are implemented as hash tables, this lookup is very quick and takes up negligible time compared to the risk of creating circular references.

Edit: I'm not worried about the import times, my problem is the visual clutter that the block of imports puts on the files.

If you only have about 4 or 5 imports like that, its not too cluttery. Remember, "Explicit is better than implicit". However if it really bothers you that much, do this:

<importheaders.py>
from django.utils import simplejson
from google.appengine.ext import webapp
from google.appengine.ext.webapp import template
from google.appengine.ext import db


<mycontroller.py>
from importheaders import *
Unknown
A: 

First you can shorten it to:

from django.utils import simplejson
from google.appengine.ext import webapp, db
from webapp import template

Secondly suppose you have those ^ imports in my_module.py

In my_module2.py you can do:

from my_module2.py import webapp, db, tempate

example:

In [5]: from my_module2 import MyMath2, MyMath

In [6]: m2 = MyMath2()

In [7]: m2.my_cos(3)
Out[7]: 0.94398413915231416

In [8]: m = MyMath()

In [9]: m.my_sin(3)
Out[9]: 0.32999082567378202

where my_module2 is:

from my_module import math, MyMath

class MyMath2(object):

    the_meaning_of_life = 42

    def my_cos(self, number):
        return math.cos(number * 42)

and my_module1 is:

import math

class MyMath(object):

    some_number = 42

    def my_sin(self, num):
        return math.sin(num * self.some_number)

Cheers, Hope it helps AleP

Ale