[Tutor] [Python-ideas] import imports

spir denis.spir at free.fr
Tue Jan 27 09:03:03 CET 2009

Le Mon, 26 Jan 2009 22:38:24 -0000,
"Alan Gauld" <alan.gauld at btinternet.com> a écrit :

> "spir" <denis.spir at free.fr> wrote
> > Here are some ideas around import. I wish to receive comments
> > The module attribute __all__ allows defining names to be exported.
> > I always use it for my own modules, and also sometimes define it in
> > external modules, when absent, or adapt it to my needs.
> I've never defined it in any of my modules. It encourages people
> to use from X import * which is nearly always a bad idea.
> > Then I'm happy with a secure "import *".
> I'm not sure what you mean by a secure import *.
> The only danger is that of name collisions and limiting the
> exported names only helps by a tiny amount. There is still
> a good chance that another module will have the same
> name exported.
> > "import *" is not recommanded for good reasons, as a
> > blind and risky practice. Now, when this is done consciously,
> > knowing that the imported module defines __all__, then
> > the meaning is totally different, if not opposite.
> Not at all. Two modules could still have conflicting names.
> I don;t see how you  can avoid it. Thats why using import foo
> is better.

"Secure import" means that I, as client of the imported module, know that this module defines __all__. I can then safely import all. I can even precisely know which names are defined simply by reading __all__. The common practice of defining __all__ on top of a module help in that, too. So that there is no name collision (or rather no more than may happen inside a module when not paying enough attention to naming.)
"Opposite" here points to the difference between blind "import *" and conscious import relying on the existence of __all__. And/Or the difference between knowing or not which names will be imported.
I also think distributed modules or packages should be encouraged to define __all__ and that their doc should explicitely list which names are defined there. Many actually do define __all__ if only for their own use: intra-package imports. Package/application developpers need to precisely specify the set of names that they import themselves from module to module, don't they?

> import foo also has the advantage of forcing code to explicitly
> flag where imported functions and classes are found. This
> makes debugging and maintence far easier.
> import * is a "bad idea" for all sorts of reasons.
> Namespaces are powerful tools - lets use them.

For sure. Either is good.

> > === package module lookup ===
> >
> > There is a similar issue at the package/application level:
> > I do not know of any practice or feature that simply allows
> > changing a filename, a directory name, or the organisation
> > of the package's directory tree, without having then to
> > correct all dependance information inside the concerned modules.
> This is a more valid issue although if you always import both
> package and subpackages directly and especially if you use
> aliases to protect your code references from change
> import foo as f

> means even if foo changes name you only need to change
> the import statement not all the references to f.x
Here, I'm rather talking of package or application maintenance. (External import issues also come into account, they may be simplified with this proposal, they they are not the primary target. See below.)

> > I would love a kind of import lookup to be based on the following 
> > assumption:
> > "The main/startup module resides in the package's root dir."
> But most packages don;t have a startup or main module. They
> are libraries that the application writer uses. Thus the app
> writer provides the main or startup module not the package writer.

I should have said application/package and more highlighted intra-package imports. Again, purely external, client imports are not the issue I'm talking about. Anyway, even purely toolbox packages are identified by an __init__.py file that is considered as a startup module that will be parsed and executed before any module or sub-package import. According to my proposal, the location of this file defines the package's root dir -- which is the practice with python packages anyway.

Even if my developpment is rather small-scale, I like to split it into modules and organise these into a properly shaped local directory tree. At developpment time, at least, even if the final product happen to fit well in a single file.
Now, I want to be free to move, rename, reorganise all of that stuff. What about you? This shouldn't be an issue! It's everyday job, isn't it? The proposal aims at letting this happen simply with either the developper or python itself, maintaining an up-to-date local module index for the application/package. Is it clearer? 


la vida e estranya

More information about the Tutor mailing list