Do not import *

It is we­ll-k­no­wn among Py­thon de­ve­lo­pers (or at leas­t, it should be­), that is a bad idea to im­port eve­r­y­thin­g ­from a mo­du­le, for exam­ple by doing from <mo­du­le> im­port *.

The idea on this pos­t, is to hi­gh­li­ght and ga­ther the rea­sons why this is a bad prac­ti­ce, in or­der to co­llec­ti­ve­l­y i­den­ti­fy many un­de­si­red effec­ts. Ho­we­ve­r, wi­thout lo­sing prag­ma­tis­m, in ca­se the­re are so­me odd rea­sons why this ­mi­ght be ac­cep­ta­ble, I wi­ll al­so men­tion the­m, if an­y. Le­t’s see whe­re we ge­t.

  1. You do not know what you get
    An ar­bi­tra­ry Py­thon script may con­tain any co­de, and most of it wi­ll be exe­cuted when ­per­for­ming the im­port * part (you can­not re­ly on how __­na­me__ is hand­le­d). ­The in­ter­fa­ce is to­ta­lly un­clea­r: you do not know what com­pu­ta­tions per­for­ms, what ob­jec­ts wi­ll im­por­t, etc. In ge­ne­ral is mo­re effi­cient to im­port as few de­fi­ni­tions as po­s­si­ble.
  2. Iden­ti­fiers appear ma­gi­ca­lly
    In any de­cen­tly rea­da­ble Py­thon scrip­t, the pro­gra­m­mer must be able to lo­ca­te eve­ry de­fi­ni­tio­n, whi­ch mean­s ­to iden­ti­fy whe­re does eve­ry iden­ti­fier co­me fro­m. For exam­ple, a va­ria­ble na­med x can ei­ther be a pa­ra­me­te­r of the func­tion in the cu­rrent sco­pe, a va­ria­ble al­ready de­fi­ned (a­s­sig­ne­d), or a na­me al­ready im­ported (from mod im­port x), etc. By per­for­ming the in­co­rrect im­por­t, this va­ria­ble mi­ght appear out of the blue, mea­ning that I wi­ll ha­ve an x tha­t wi­ll not be nei­ther a pa­ra­me­te­r, nor a de­fi­ni­tion nor a de­cla­red im­por­t. This mean­s, I can­no­t ­tra­ck the ori­gin or x. The si­tua­tion ge­ts wor­se if the­re are not one, but many im­port * sta­te­men­ts. ­De­bu­gging be­co­mes a ni­ght­ma­re.
  3. Na­mes­pa­ces are one ho­nking great idea — le­t’s do mo­re of tho­se!
    Strai­ght from the Py­thon zen [1]. By im­por­ting eve­r­y­thing from a mo­du­le, the be­ne­fi­ts of the na­mes­pa­ce­s a­re so­me­how los­t. Ins­tea­d, eve­r­y­thing (or a lot of things), mi­ght get to be ca­lled the sa­me, me­s­sin­g wi­th the cu­rrent sco­pe. Mo­reo­ve­r, new im­port de­fi­ni­tions mi­ght ove­rri­de pre­vious ones.
  4. Ex­pli­cit is be­tter than im­pli­cit
    Agai­n, eve­ry iden­ti­fier that we want im­ported should be do­ne ex­pli­ci­tly (the * is not ve­ry de­cla­ra­ti­ve).

No­w, so far the­se mi­ght be so­me of the main rea­sons about why im­por­ting eve­r­y­thing from a Py­thon mo­du­le is usua­lly not a good idea. Ho­we­ve­r, in ca­se the co­de at stake is just a sim­ple tes­ting scrip­t, or an in-­li­ne sen­ten­ce on ip­y­tho­n, the­re could be no­thing wrong about it.

In addi­tio­n, al­thou­gh I am not a big fan of im­port sta­te­men­ts in­si­de func­tions (so­me­ti­mes they are ne­ce­ssar­y, thou­gh), im­por­ting eve­r­y­thing from a pa­cka­ge wi­thin a func­tion is not a big pro­ble­m, be­cau­se the sco­pe is al­ready na­rro­we­d.

Just to be clea­r, this is by no means an ab­so­lu­te sta­te­men­t, but an idea pre­sen­ted in or­der to wri­te be­tter co­de. O­ne of the things I like the most about Py­thon is that en­cou­ra­ges good prac­ti­ce­s. The­re­fo­re, if I rea­d an im­port sta­te­ment like this, un­le­ss the­re are so­me ve­ry good rea­sons to do so, I wi­ll thi­nk that li­ne as a co­de-s­me­ll [2].

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