Relative-importing *

Steven D'Aprano steve at REMOVE.THIS.cybersource.com.au
Sat Jul 28 08:17:40 CEST 2007


On Sat, 28 Jul 2007 09:05:51 +1000, Ben Finney wrote:

> rbygscrsepda at gmail.com writes:
> 
>>     from . import *
>>     from .sibiling import *
>>     from .. import *
>>     from ..parent_sibling import *
>> 
>> ...and so on. The same error occurs:
>>     SyntaxError: 'import *' not allowed with 'from .'
> 
> Interesting. I know that 'from foo import *' is frowned on 

Well, it is discouraged, unless it is the right thing to do, in which case
it is encouraged. It's only frowned upon when it is the wrong thing to do.


And later, Ben continued:

> While waiting, you should take it as an opportunity to remove the
> blight of "from foo import *". All imports should explicitly import
> names, not implicitly clobber the current namespace with whatever pops
> out. 

That word you use, implicit -- I do not think it means what you think it
means.

I read "from module import *" as explicitly saying "clobber the current
namespace with whatever names module exports". That's what from does: it
imports names into the current namespace. It isn't some sort of easy to
miss side-effect. If a name already existed, it gets clobbered, just like
any other import:

>>> math = 45
>>> import math # clobber any existing name 'math'
>>> math 
<module 'math' from '/usr/local/lib/python2.5/lib-dynload/math.so'>

I do take your point that importing * has the potential to unexpectedly
clobber names you didn't intend, and that's a good reason to avoid it
unless you have a good reason to use it. But there are good reasons.

The "from module import *" statement is very useful if you wish to export
all the public objects from a "private" module, e.g. emulate what the os
module does with platform specific functions. It is an excellent way of
reducing the amount of duplicated data that needs to be maintained in
multiple places. E.g. instead of:

# export some public functions, which are defined differently at 
# run-time, but must all exist
if lights_are_green:
    from green_module import (dead_parrot, spanish_inquisition,
    knights_who_say_ni, wafer_thin_mints)
else:
    from red_module import (dead_parrot, spanish_inquisition,
    knights_who_say_ni, wafer_thin_mints)

you can Do The Right Thing with:

if lights_are_green:
    from green_module import *
else:
    from red_module import *

and so long as green_module and red_module also Do The Right Thing it will
Just Work. Indeed, sub-modules can add extra functions to their public
API, and you don't need to do anything to support them: it also Just
Works. Python has a mechanism for making it work: modules can define what
their public API is, thus avoiding the possibility of exporting things you
didn't intend to.

__all__ = ["dead_parrot", "spanish_inquisition",
    "knights_who_say_ni", "wafer_thin_mints", "ethel_the_aardvark"]

(Naturally, if the modules' __all__ doesn't match the API you are
expecting from the documentation, strange and terrible things might occur;
but importing _anything_ from a broken module may do strange and terrible
things.)

I certainly agree that "from module import *" is easily abused, but to go
from there to the conclusion that it is a blight that must be stamped out
is far too strong.

But back to the relative imports... I've spent some time reading the
documentation, and googling, and I can't find any clue why importing *
from a package is prohibited. I do know that it is prohibited inside a
function or method (and rightly so!).


-- 
Steven.




More information about the Python-list mailing list