Relative Imports, why the hell is it so hard?

Gabriel Genellina gagsl-py2 at yahoo.com.ar
Tue Mar 24 20:16:31 CET 2009


En Tue, 24 Mar 2009 12:49:08 -0300, Istvan Albert  
<istvan.albert at gmail.com> escribió:
> On Mar 23, 10:16 am, CinnamonDonkey <CinnamonDon... at googlemail.com>
> wrote:
>
>> I'm fairly new to Python so I still have a lot to learn. But I'd like
>> to know how to correectly use relative imports.
>
> Relative imports are *fundamentally* broken in python. You will soon
> see that code using relative import will break if you attempt to run
> the module on its own. Yes, it is mindboggling!

How import works in general is hard to grasp -- the semantics are rather  
complicated, partly because the import system has grown patch over patch  
over the years, and because it's mostly underdocumented.
But I would not say that relative imports are "fundamentally broken" --  
they're one of the best improvements to the import system!

> Why is it so you ask? It is one of those issue that would be trivial
> to implement correctly (it is relative to the current file location,
> duh!!!), would be tremendously useful yet  for some reason it is
> controversial with those who would need to implement it.

A module doesn't *have* to reside in the filesystem - so in the general  
case, there is no such thing as "current file location". Packages provide  
such hierarchical disposition - and relative imports work with packages  
only.

> It looks like they think that the expected mode of operation would
> greatly confuse the 'rest' of us. So that is the reason you end up
> with a broken implementation that is worse than not having it at all.
> All I can do is recommend that you avoid relative imports.

I'd recommend the oposite - use relative (intra-package) imports when  
possible. Explicit is better than implicit - and starting with 2.7 -when  
"absolute" import semantics will be enabled by default- you'll *have* to  
use relative imports inside a package, or fail.

> The easiest way around the issue is to create a module named
> pathfix.py like the one below and import it in all of your modules.
> This is the only way to fix this issue in a way that does not come
> back and bite you, it is ugly, you are repeating yourself in multiple
> places, but it is still better than the alternative.

"import it in all of your modules"?
Did you know, once a module is imported by the first time, subsequent  
imports simply return the same module instance? The initialization code is  
not executed again.

> import os, sys
>
> def path_join(*args):
>     return os.path.abspath(os.path.join(*args))
>
> # adds base directory to import path to allow relative imports
> __currdir = os.path.dirname( __file__ )
> __basedir = path_join(__currdir, '..' )
> if __basedir not in sys.path:
>     sys.path.append( __basedir )

I don't understand, how is this supposed to help relative imports?
Bindly inserting directories into sys.path can easily confuse the import  
system (and you!)

-- 
Gabriel Genellina




More information about the Python-list mailing list