Do not import *

It is well-­known among Python de­vel­op­ers (or at least, it should be), that is a bad idea to im­port ev­ery­thing from a mod­ule, for ex­am­ple by do­ing from <mod­ule> im­port *.

The idea on this post, is to high­light and gath­er the rea­sons why this is a bad prac­tice, in or­der to col­lec­tive­ly i­den­ti­fy many un­de­sired ef­fect­s. How­ev­er, with­out los­ing prag­ma­tism, in case there are some odd rea­sons why this might be ac­cept­able, I will al­so men­tion them, if any. Let’s see where we get.

  1. You do not know what you get
    An ar­bi­trary Python script may con­tain any code, and most of it will be ex­e­cut­ed when per­form­ing the im­port * part (y­ou can­not re­ly on how __­name__ is han­dled). The in­ter­face is to­tal­ly un­clear: you do not know what com­pu­ta­tions per­form­s, what ob­jects will im­port, etc. In gen­er­al is more ef­fi­cient to im­port as few def­i­ni­tions as pos­si­ble.
  2. Iden­ti­fiers ap­pear mag­i­cal­ly
    In any de­cent­ly read­able Python scrip­t, the pro­gram­mer must be able to lo­cate ev­ery def­i­ni­tion, which mean­s ­to iden­ti­fy where does ev­ery iden­ti­fi­er come from. For ex­am­ple, a vari­able named x can ei­ther be a pa­ram­e­ter of the func­tion in the cur­rent scope, a vari­able al­ready de­fined (as­signed), or a name al­ready im­port­ed (from mod im­port x), etc. ­By per­form­ing the in­cor­rect im­port, this vari­able might ap­pear out of the blue, mean­ing that I will have an x that will not be nei­ther a pa­ram­e­ter, nor a def­i­ni­tion nor a de­clared im­port. This mean­s, I can­not ­track the ori­gin or x. The sit­u­a­tion gets worse if there are not one, but many im­port * state­ments. De­bug­ging be­comes a night­mare.
  3. Names­paces are one honk­ing great idea — let’s do more of those!
    Straight from the Python zen [1]. By im­port­ing ev­ery­thing from a mod­ule, the ben­e­fits of the names­paces are some­how lost. In­stead, ev­ery­thing (or a lot of things), might get to be called the same, mess­ing with the cur­rent scope. More­over, new im­port def­i­ni­tions might over­ride pre­vi­ous ones.
  4. Ex­plic­it is bet­ter than im­plic­it
    Again, ev­ery iden­ti­fi­er that we want im­port­ed should be done ex­plic­it­ly (the * is not very declar­a­tive).

Now, so far these might be some of the main rea­sons about why im­port­ing ev­ery­thing from a Python mod­ule is usu­al­ly not a good idea. How­ev­er, in case the code at stake is just a sim­ple test­ing scrip­t, or an in­-­line sen­tence on ipython, there could be noth­ing wrong about it.

In ad­di­tion, al­though I am not a big fan of im­port state­ments in­side func­tions (some­times they are nec­es­sary, though), im­port­ing ev­ery­thing from a pack­age with­in a func­tion is not a big prob­lem, be­cause the scope is al­ready nar­rowed.

Just to be clear, this is by no means an ab­so­lute state­men­t, but an idea pre­sent­ed in or­der to write bet­ter code. One of the things I like the most about Python is that en­cour­ages good prac­tices. There­fore, if I read­ an im­port state­ment like this, un­less there are some very good rea­sons to do so, I will think that line as a code-s­mell [2].

[1] import this
[2] https://c2.com/cgi/wiki?CodeSmell