Reputation: 5097
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.
Upvotes: 3
Views: 526
Reputation: 1345
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
Upvotes: 0
Reputation: 46781
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 *
Upvotes: 13
Reputation: 31512
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(...)
....
Upvotes: 0
Reputation: 42183
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
>>>
Upvotes: 1
Reputation: 19029
Sounds like you are wanting to use python packages. Look into those.
Upvotes: 0
Reputation: 34155
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.
Upvotes: 0