views:

133

answers:

2

here at office we have a library named after the company name and inside of it sublibraries, per project more or less, and in each sublibrary there might be more modules or libraries. we are using Django and this makes our hierarchy a couple of steps deeper...

I am a bit perplex about the differences among the following import instructions:

1:

import company.productline.specific.models, company.productline.base.models
specific, base = company.productline.specific, company.productline.base
2:

import company.productline.specific.models, company.productline.base.models
from company.productline import specific, base

3:

from company.productline import specific, base
import company.productline.specific.models, company.productline.base.models

the first style imports only the models? what are then the names specific and base made available in the current namespace?

what happens in the initialization of modules if one imports first submodules and only afterwards the containing libraries?

maybe the neatest style is the last one, where it is clear (at least to me) that I first import the two modules and putting their names directly in the current namespace and that the second import adds the model submodule to both modules just imported.

on the other hand, (1) allows me to import only the inner modules and to refer to them in a compact though clear way (specific.models and base.models)

not so sure whether this is question, but I'm curious to read comments.

A: 

The three examples above are all equivalent in practice. All of them are weird, though. There is no reason to do

from company.productline import specific

and

import company.productline.specific.models

You can (most of the time) just access models by specific.models after the first import.

It seems reasonable to in this case do

from company.productline import base
from company.productline import specific

And then access these like base.models, specific.whatever, etc. If "specific" is a you also need to do a import model in __init__.py to be able to access specific.module.

Lennart Regebro
I had a look at the standard email package, which contains various deeper modules and it defines no `__all__` (useful only for `from package import *`), rather it does some fancy things with lazy importing... quite interesting. tried a `__init__.py` containing a `import models`, but what django does behind the scenes when python imports models makes it impossible to do so (django scans `INSTALLED_APPS` and assumes they are already there, while python is still importing it)
mariotomo
A, right __all__ is only for *, right. To fix the "empty module" you import the submodule in the __init__. I remembered it backwards. :)
Lennart Regebro
A: 

so I have looked into it a bit deeper, using this further useless package:

A:(__init__.py: print 'importing A',
   B:(__init__.py: print 'importing B',
      C1:(__init__.py: print 'importing C1',
          D:(__init__.py: print 'importing D'))
      C2:(__init__.py: print 'importing C2',
          D:(__init__.py: print 'importing D'))))

notice that C1 and C2 contain two different modules, both named D in their different namespaces. I will need them both, I don't want to use the whole path A.B.C1.D and A.B.C2.D because that looks too clumsy and I can't put them both in the current namespace because one would overwrite the other and -no- I don't like the idea of changing their names. what I want is to have C1 and C2 in the current namespace and to load the two included D modules.

oh, yes: and I want the code to be readable.

I tried the two forms

from A.B import C1

and the much uglier one

import A.B.C1
C1 = A.B.C1

and I would conclude that they are equivalent:


Python 2.6.2 (release26-maint, Apr 19 2009, 01:56:41) [GCC 4.3.3] on linux2
>>> from A.B import C1
importing A
importing B
importing C1
>>> C1
<module 'A.B.C1' from 'A/B/C1/__init__.pyc'>
>>>


Python 2.6.2 (release26-maint, Apr 19 2009, 01:56:41) [GCC 4.3.3] on linux2
>>> import A.B.C1
importing A
importing B
importing C1
>>> C1=A.B.C1
>>> C1
<module 'A.B.C1' from 'A/B/C1/__init__.pyc'>
>>>

Importing package C1 or C2 does not import included modules just because they are there. and too bad that the form from A.B import C1.D is not syntactically accepted: that would be a nice compact thing to have.

on the other hand, I am offered the opportunity to do so in A.B.C1.__init__.py if I please. so if I append the line import D to the __init__.py in A.B.C1, this is what happens:

Python 2.6.2 (release26-maint, Apr 19 2009, 01:56:41) [GCC 4.3.3] on linux2
>>> from A.B import C1
importing A
importing B
importing C1
importing D
>>>

importing included modules is probably best done at the end of the package initialization.


considering all this and in given some specific django behaviour (that makes it difficult/impossible to automatically import models while importing the package), I think I prefer style 3.

mariotomo