{"id":6209,"date":"2016-08-11T16:52:59","date_gmt":"2016-08-11T15:52:59","guid":{"rendered":"http:\/\/www.walkingrandomly.com\/?p=6209"},"modified":"2016-08-11T16:55:32","modified_gmt":"2016-08-11T15:55:32","slug":"python-rant-from-foo-import-is-bad","status":"publish","type":"post","link":"https:\/\/walkingrandomly.com\/?p=6209","title":{"rendered":"Python rant: &#8216; from foo import * &#8216; is bad"},"content":{"rendered":"<p>This is my rant on <strong>import *.<\/strong> There are <a href=\"http:\/\/stackoverflow.com\/questions\/2386714\/why-is-import-bad\">many like it<\/a>, but this one is mine.<\/p>\n<p>I tend to work with scientists so I&#8217;ll use something from mathematics as my example. \u00a0What is the result of executing the following line of Python code?<\/p>\n<pre>result = sqrt(-1)\r\n<\/pre>\n<p>Of course, you have no idea if you don&#8217;t know which module <strong>sqrt<\/strong> came from. Let&#8217;s look at a few possibilities. Perhaps you&#8217;ll get an exception:<\/p>\n<pre>In [1]: import math\r\nIn [2]: math.sqrt(-1)\r\n---------------------------------------------------------------------------\r\nValueError Traceback (most recent call last)\r\nin ()\r\n----&gt; 1 math.sqrt(-1)\r\n\r\nValueError: math domain error\r\n<\/pre>\n<p>Or maybe you&#8217;ll just get a warning and a nan<\/p>\n<pre>In [3]: import numpy\r\nIn [4]: numpy.sqrt(-1)\r\n\/Users\/walkingrandomly\/anaconda\/bin\/ipython:1: RuntimeWarning: invalid value encountered in sqrt\r\n#!\/bin\/bash \/Users\/walkingrandomly\/anaconda\/bin\/python.app\r\nOut[4]: nan\r\n<\/pre>\n<p>You might get an answer but the datatype of your answer could be all sorts of strange and wonderful stuff.<\/p>\n<pre>In [5]: import cmath\r\nIn [6]: cmath.sqrt(-1)\r\nOut[6]: 1j\r\nIn [7]: type(cmath.sqrt(-1))\r\nOut[7]: complex\r\n\r\nIn [8]: import scipy\r\nIn [9]: scipy.sqrt(-1)\r\nOut[9]: 1j\r\nIn [10]: type(scipy.sqrt(-1))\r\nOut[10]: numpy.complex128\r\n\r\nIn [11]: import sympy\r\nIn [12]: sympy.sqrt(-1)\r\nOut[12]: I\r\nIn [13]: type(sympy.sqrt(-1))\r\nOut[13]: sympy.core.numbers.ImaginaryUnit\r\n<\/pre>\n<p>Even the humble square root function behaves very differently when imported from different modules! There are probably other sqrt functions, with yet more behaviours that I&#8217;ve missed.<\/p>\n<p>Sometimes, they seem to behave in very similar ways:-<\/p>\n<pre>In [16]: math.sqrt(2)\r\nOut[16]: 1.4142135623730951\r\n\r\nIn [17]: numpy.sqrt(2)\r\nOut[17]: 1.4142135623730951\r\n\r\nIn [18]: scipy.sqrt(2)\r\nOut[18]: 1.4142135623730951\r\n<\/pre>\n<p>Let&#8217;s invent some trivial code.<\/p>\n<pre>from scipy import sqrt\r\n\r\nx = float(input('enter a number\\n'))\r\ny = sqrt(x)\r\n\r\n# important things happen after here. Complex numbers are fine!\r\n<\/pre>\n<p>I can input -1 just fine. Then, someone comes along and decides that they need a function from <b>math<\/b> in the &#8216;important bit&#8217;. They use <strong>import *<\/strong><\/p>\n<pre>from scipy import sqrt\r\nfrom math import *\r\n\r\nx = float(input('enter a number\\n'))\r\ny = sqrt(x)\r\n\r\n# important things happen after here. Complex numbers are fine!\r\n<\/pre>\n<p>They test using inputs like 2 and 4 and everything works (we don&#8217;t have automated tests &#8212; we suck!). Of course it breaks for -1 now though. This is easy to diagnose when you&#8217;ve got a few lines of code but it causes a lot of grief when there&#8217;s hundreds&#8230;or, horror of horrors, if the <strong>&#8216;from math import *&#8217;<\/strong> was done somewhere in the middle of the source file!<\/p>\n<p>I&#8217;m sometimes accused of being obsessive and maybe I&#8217;m labouring the point a little but I see this stuff, in various guises, all the time!<\/p>\n<p>So, yeah, don&#8217;t use <strong>import *<\/strong>.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>This is my rant on import *. There are many like it, but this one is mine. I tend to work with scientists so I&#8217;ll use something from mathematics as my example. \u00a0What is the result of executing the following line of Python code? result = sqrt(-1) Of course, you have no idea if you [&hellip;]<\/p>\n","protected":false},"author":3,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"jetpack_post_was_ever_published":false,"footnotes":"","jetpack_publicize_message":"","jetpack_publicize_feature_enabled":true,"jetpack_social_post_already_shared":true,"jetpack_social_options":{"image_generator_settings":{"template":"highway","default_image_id":0,"font":"","enabled":false},"version":2}},"categories":[7,31],"tags":[],"class_list":["post-6209","post","type-post","status-publish","format-standard","hentry","category-programming","category-python"],"jetpack_publicize_connections":[],"jetpack_featured_media_url":"","jetpack_shortlink":"https:\/\/wp.me\/p3swhs-1C9","jetpack_sharing_enabled":true,"_links":{"self":[{"href":"https:\/\/walkingrandomly.com\/index.php?rest_route=\/wp\/v2\/posts\/6209","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/walkingrandomly.com\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/walkingrandomly.com\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/walkingrandomly.com\/index.php?rest_route=\/wp\/v2\/users\/3"}],"replies":[{"embeddable":true,"href":"https:\/\/walkingrandomly.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=6209"}],"version-history":[{"count":5,"href":"https:\/\/walkingrandomly.com\/index.php?rest_route=\/wp\/v2\/posts\/6209\/revisions"}],"predecessor-version":[{"id":6215,"href":"https:\/\/walkingrandomly.com\/index.php?rest_route=\/wp\/v2\/posts\/6209\/revisions\/6215"}],"wp:attachment":[{"href":"https:\/\/walkingrandomly.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=6209"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/walkingrandomly.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=6209"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/walkingrandomly.com\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=6209"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}