(window.webpackJsonp=window.webpackJsonp||[]).push([[2781],{3190:function(t,e,s){"use strict";s.r(e);var a=s(31),n=Object(a.a)({},(function(){var t=this,e=t.$createElement,s=t._self._c||e;return s("ContentSlotsDistributor",{attrs:{"slot-key":t.$parent.slotKey}},[s("h1",{attrs:{id:"python-anti-patterns"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#python-anti-patterns"}},[t._v("#")]),t._v(" Python Anti-Patterns")]),t._v(" "),s("h2",{attrs:{id:"overzealous-except-clause"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#overzealous-except-clause"}},[t._v("#")]),t._v(" Overzealous except clause")]),t._v(" "),s("p",[t._v("Exceptions are powerful, but a single overzealous except clause can take it all away in a single line.")]),t._v(" "),s("p",[t._v("This example demonstrates 3 symptoms of the antipattern:")]),t._v(" "),s("ol",[s("li",[t._v("The "),s("code",[t._v("except")]),t._v(" with no exception type (line 5) will catch even healthy exceptions, including "),s("a",{attrs:{href:"https://docs.python.org/2/library/exceptions.html#exceptions.KeyboardInterrupt",target:"_blank",rel:"noopener noreferrer"}},[s("code",[t._v("KeyboardInterrupt")]),s("OutboundLink")],1),t._v(". That will prevent the program from exiting in some cases.")]),t._v(" "),s("li",[t._v("The except block does not reraise the error, meaning that we won't be able to tell if the exception came from within "),s("code",[t._v("get_result")]),t._v(" or because "),s("code",[t._v("res")]),t._v(" was an empty list.")]),t._v(" "),s("li",[t._v("Worst of all, if we were worried about result being empty, we've caused something much worse. If "),s("code",[t._v("get_result")]),t._v(" fails, "),s("code",[t._v("res")]),t._v(" will stay completely unset, and the reference to "),s("code",[t._v("res")]),t._v(" in the except block, will raise "),s("a",{attrs:{href:"https://docs.python.org/2/library/exceptions.html#exceptions.NameError",target:"_blank",rel:"noopener noreferrer"}},[s("code",[t._v("NameError")]),s("OutboundLink")],1),t._v(", completely masking the original error.")])]),t._v(" "),s("p",[t._v("Always think about the type of exception you're trying to handle. Give "),s("a",{attrs:{href:"https://docs.python.org/2/library/exceptions.html",target:"_blank",rel:"noopener noreferrer"}},[t._v("the exceptions page a read"),s("OutboundLink")],1),t._v(" and get a feel for what basic exceptions exist.")]),t._v(" "),s("p",[t._v("Here is a fixed version of the example above:")]),t._v(" "),s("p",[t._v("We catch more specific exceptions, reraising where necessary. A few more lines, but infinitely more correct.")]),t._v(" "),s("h2",{attrs:{id:"looking-before-you-leap-with-processor-intensive-function"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#looking-before-you-leap-with-processor-intensive-function"}},[t._v("#")]),t._v(" Looking before you leap with processor-intensive function")]),t._v(" "),s("p",[t._v("A program can easily waste time by calling a processor-intensive function multiple times.")]),t._v(" "),s("p",[t._v("For example, take a function which looks like this: it returns an integer if the input "),s("code",[t._v("value")]),t._v(" can produce one, else "),s("code",[t._v("None")]),t._v(":")]),t._v(" "),s("div",{staticClass:"language-py extra-class"},[s("pre",{pre:!0,attrs:{class:"language-py"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("def")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("intensive_f")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("value"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("# int -> Optional[int]")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("# complex, and time-consuming code")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("if")]),t._v(" process_has_failed"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("return")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token boolean"}},[t._v("None")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("return")]),t._v(" integer_output\n\n")])])]),s("p",[t._v("And it could be used in the following way:")]),t._v(" "),s("div",{staticClass:"language-py extra-class"},[s("pre",{pre:!0,attrs:{class:"language-py"}},[s("code",[t._v("x "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("5")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("if")]),t._v(" intensive_f"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("x"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("is")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("not")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token boolean"}},[t._v("None")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("print")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("intensive_f"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("x"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("/")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("2")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("else")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("print")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("x"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"could not be processed"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("print")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("x"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n\n")])])]),s("p",[t._v("Whilst this will work, it has the problem of calling "),s("code",[t._v("intensive_f")]),t._v(", which doubles the length of time for the code to run. A better solution would be to get the return value of the function beforehand.")]),t._v(" "),s("div",{staticClass:"language-py extra-class"},[s("pre",{pre:!0,attrs:{class:"language-py"}},[s("code",[t._v("x "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("5")]),t._v("\nresult "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" intensive_f"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("x"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("if")]),t._v(" result "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("is")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("not")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token boolean"}},[t._v("None")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("print")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("result "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("/")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("2")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("else")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("print")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("x"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"could not be processed"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n\n")])])]),s("p",[t._v("However, a clearer and "),s("a",{attrs:{href:"https://docs.python.org/3/glossary.html#term-eafp",target:"_blank",rel:"noopener noreferrer"}},[t._v("possibly more pythonic way"),s("OutboundLink")],1),t._v(" is to use exceptions, for example:")]),t._v(" "),s("div",{staticClass:"language-py extra-class"},[s("pre",{pre:!0,attrs:{class:"language-py"}},[s("code",[t._v("x "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("5")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("try")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("print")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("intensive_f"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("x"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("/")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("2")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("except")]),t._v(" TypeError"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("# The exception raised if None + 1 is attempted")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("print")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("x"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"could not be processed"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n\n")])])]),s("p",[t._v("Here no temporary variable is needed. It may often be preferable to use a "),s("code",[t._v("assert")]),t._v(" statement, and to catch the "),s("code",[t._v("AssertionError")]),t._v(" instead.")]),t._v(" "),s("h3",{attrs:{id:"dictionary-keys"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#dictionary-keys"}},[t._v("#")]),t._v(" Dictionary keys")]),t._v(" "),s("p",[t._v("A common example of where this may be found is accessing dictionary keys. For example compare:")]),t._v(" "),s("div",{staticClass:"language-py extra-class"},[s("pre",{pre:!0,attrs:{class:"language-py"}},[s("code",[t._v("bird_speeds "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" get_very_long_dictionary"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("if")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"european swallow"')]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("in")]),t._v(" bird_speeds"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v("\n speed "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" bird_speeds"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"european swallow"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("else")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v("\n speed "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("input")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"What is the air-speed velocity of an unladen swallow?"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("print")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("speed"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n\n")])])]),s("p",[t._v("with:")]),t._v(" "),s("div",{staticClass:"language-py extra-class"},[s("pre",{pre:!0,attrs:{class:"language-py"}},[s("code",[t._v("bird_speeds "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" get_very_long_dictionary"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("try")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v("\n speed "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" bird_speeds"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"european swallow"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("except")]),t._v(" KeyError"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v("\n speed "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token builtin"}},[t._v("input")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"What is the air-speed velocity of an unladen swallow?"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("print")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("speed"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n\n")])])]),s("p",[t._v("The first example has to look through the dictionary twice, and as this is a long dictionary, it may take a long time to do so each time. The second only requires one search through the dictionary, and thus saves a lot of processor time.")]),t._v(" "),s("p",[s("strong",[t._v("An alternative to this is to use "),s("code",[t._v("dict.get(key, default)")]),t._v(", however many circumstances may require more complex operations to be done in the case that the key is not present")])])])}),[],!1,null,null,null);e.default=n.exports}}]);