Relative Imports, why the hell is it so hard?
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>
>> 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
> 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!)
More information about the Python-list