TE
TechEcho
Home24h TopNewestBestAskShowJobs
GitHubTwitter
Home

TechEcho

A tech news platform built with Next.js, providing global tech news and discussions.

GitHubTwitter

Home

HomeNewestBestAskShowJobs

Resources

HackerNews APIOriginal HackerNewsNext.js

© 2025 TechEcho. All rights reserved.

Python exceptions considered an anti-pattern

47 pointsby sobolevnover 6 years ago

23 comments

mindslightover 6 years ago
It amazes me how enduring formulaic it is to single out some particular design tradeoff of a language, draw up some examples of expressing something where that tradeoff creates worse code, and then act like it&#x27;s some mortal flaw in the language.<p>Python chose untyped exceptions, period. How is this surprising, given that its basis is untyped parameters?<p>If you don&#x27;t like that, use Java with its checked exceptions. Or remove exceptions from the implicit monad altogether and use C or Rust. Just don&#x27;t then go on to write some lengthy post about how any one of those is too explicit.
评论 #19146496 未加载
评论 #19146528 未加载
评论 #19146635 未加载
评论 #19146868 未加载
评论 #19146719 未加载
detaroover 6 years ago
The interesting bit starts at <a href="https:&#x2F;&#x2F;sobolevn.me&#x2F;2019&#x2F;02&#x2F;python-exceptions-considered-an-antipattern#how-to-be-safe" rel="nofollow">https:&#x2F;&#x2F;sobolevn.me&#x2F;2019&#x2F;02&#x2F;python-exceptions-considered-an-...</a>, where it introduces a library for wrapping errors in return types, even if it got little to do with the headline. IMHO the article would be stronger with a title about what it presents and without the first half.
评论 #19146624 未加载
评论 #19134115 未加载
chillacyover 6 years ago
Counterargument: Exceptions are Pythonic <a href="https:&#x2F;&#x2F;jeffknupp.com&#x2F;blog&#x2F;2013&#x2F;02&#x2F;06&#x2F;write-cleaner-python-use-exceptions&#x2F;" rel="nofollow">https:&#x2F;&#x2F;jeffknupp.com&#x2F;blog&#x2F;2013&#x2F;02&#x2F;06&#x2F;write-cleaner-python-u...</a>
评论 #19146480 未加载
评论 #19146600 未加载
kissgyorgyover 6 years ago
I never understood, that people who don&#x27;t understand Python at all, or don&#x27;t like essential Python constructs, why they bother using it? Why not use a different language in the first place? If you are using this library, you are not writing Python anymore and you lost the biggest advantage of the language: simplicity.
评论 #19146482 未加载
ltbarcly3over 6 years ago
&quot;X considered an anti-pattern&quot; article titles considered an anti-pattern
评论 #19146529 未加载
1337shadowover 6 years ago
Title should be &quot;another person on internet considers it an antipattern&quot;.<p>I&#x27;m part of the people who advocate automated testing and insanely high coverage. Does that mean I want to write all tests manually ? No, I use fuzzers, light test code against many autogenerated fixtures and the like, and get no runtime exceptions.<p>Duck typing means &quot;bad language&quot; for some people, for me it means &quot;freedom&quot;.
eemaxover 6 years ago
The library described in this blog post looks kind of interesting as an implementation of a Maybe monad in python, but the example case is pretty silly.<p>It re-implements a 4 line function as a 13 line class, but the logic at the caller doesn&#x27;t get any simpler:<p><pre><code> try: result = get_user_profile(id) except: # handle any exceptions... </code></pre> vs. with the library:<p><pre><code> result = FetchUserProfile(id) if (result is a Failure): # handle the failure # do something with the result</code></pre>
Glenchover 6 years ago
I&#x27;m glad this issue is getting some attention. I found the &quot;Exceptions are not exceptional&quot; section to capture something I&#x27;ve noticed several times — that code in Python can fail at a huge number of points even in a small function, nevermind the many exceptions that might happen in nested functions, or code we&#x27;re using from libraries.<p>We should have language-level mechanisms for being explicit about what&#x27;s supposed to happen when unexpected situations happen.
评论 #19146155 未加载
评论 #19146192 未加载
skrebbelover 6 years ago
Any sufficiently typed programming language will grow a vocal subcommunity that will try writing Haskell in it.
epageover 6 years ago
Since using Rust, I&#x27;ve longed for this in Python but<p>- imo it effectively requires using type checking (mypy)<p>- Too out of place with the rest of the python ecosystem (even if I like something, I&#x27;d rather not force non-standard practices on others dealing with my code)
评论 #19146059 未加载
sslnxover 6 years ago
Here is the greatest inconvenience of Python exceptions for me. Say you have to try 10 different methods, and you only need one to work. Then you have to write 10 try...except blocks so that each next block is indented relative to previous. This creates unreadable code and does not scale for say 100 methods. The solution that came to mind is labeling try blocks and referring them in except blocks. For example:<p><pre><code> try as method1: method1() except@method1 try as method2: method2() except@method2 try as method3: method3() except@method3: raise NoMethodWorked()</code></pre>
评论 #19147115 未加载
评论 #19147127 未加载
评论 #19146661 未加载
评论 #19146659 未加载
bvrmnover 6 years ago
&gt; There are so maybe potential problems with these three lines of code, that it is easier to say that it only accidentally works.<p>A very strong and emotional point. Accidentally working code <i>will</i> have exceptional handling because of problems during development.<p>The whole article is depreciated by naive library implementation because unwrap() hides source of original exception. Sadly it&#x27;s not even a POC.<p>Edit: Failure doesn&#x27;t capture trace information at all. Library users will get unusable error in a wrong place.
yarrelover 6 years ago
&gt; So, the sad conclusion is: all problems must be resolved individually depending on a specific usage context.<p>...and that&#x27;s a good thing.<p>Recognising that specific usage contexts require specific recovery strategies is a key part of effective program design.<p>Division by zero is an exception, yes. That&#x27;s basic math.<p>Getting to the point where one of your inputs is &quot;bad&quot; (zero in this case) shows that you have a problem. You should either catch zero up front with a conditional or catch it when it blows up, with an exception. Python favors the latter.<p>But without context you don&#x27;t know what that bad input <i>means</i> and so you cannot &quot;fix&quot; division by zero in the general case because it isn&#x27;t the division by zero that is the <i>cause</i> of the problem.<p>Asking &quot;what should a division by zero actually return?&quot; is the wrong question asked at the wrong point with the wrong information. Does the zero indicate lack of initialization? Does it indicate an empty container or volume? Does it indicate absence? How much of a problem to the logic of the program is this particular zero? How much of a problem is it for the person running it?<p>So while I personally dislike exceptions and prefer return codes, exceptions are just the messenger here and they are an effective messenger. Don&#x27;t shoot them.
评论 #19154328 未加载
X-Istenceover 6 years ago
It all feels very Go-ish&#x2F;Java-ish to me vs Pythonic.
评论 #19146232 未加载
sarah180over 6 years ago
If you&#x27;re not Dijkstra, Hoare, Knuth or a principal contributor to the language&#x27;s design, I would refrain from &quot;considered (harmful|anti-pattern|…).&quot;<p>It&#x27;s hyperbolic and frames your position in a way that&#x27;s likely to create poison. The people without enough experience &amp; knowledge to evaluate your argument critically are likely to end up parroting it and looking like fools. The people who <i>can</i> evaluate your argument critically are going to scrutinize it much more carefully because you&#x27;ve taken an absolutist position.<p>Unless you have the knowledge &amp; authority to really make such an absolute statement you do yourself and your readers a disservice.
rs23296008n1over 6 years ago
Putting the exception handling inside the divide is foolish. Put the handler outside in the calling function where decisions about why it happened can be implemented.<p>Python could use a &quot;raises&quot; keyword though. Whether that has real benefits is debatable.
mistrial9over 6 years ago
news flash - there is no perfect system for this.. Its a feature of Python IMO that a coder can just write a few lines and run.. some architectures may not need good error handling, except for development e.g. ephemeral data flows<p>Lazy is good (sometimes)
bvrmnover 6 years ago
I have a question. How proposed solution can solve problem with exceptional control flow? Monadic approach skips calculations under the cover and one need to track branching in his head.
rffnover 6 years ago
Calling a personal opinion an anti-pattern is an anti-pattern.
评论 #19147804 未加载
proc0over 6 years ago
Yet another Monad tutorial in disguise. Good review of exceptions, etc., and how to handle them. tl;dr: Use Maybe and Either instances (or equivalent GADTs) for better control flow.
giancarlostoroover 6 years ago
And here I am using exceptions to do HTTP redirects with CherryPy. I haven&#x27;t had major issues with exception handling in Python yet.
ltbarcly3over 6 years ago
Lets all agree that it is impossible to write code that will never have an unexpected outcome. Imagine that we somehow write a function that is totally bullet-proof. It can&#x27;t fail, it will always do precisely what it was intended to do. Further, lets say whenever we run this function we run it on N computers and take the consensus result if any of the computers disagree. No matter how large N is, if we run the function enough times eventually we will get a majority of the computers to agree, return the same result, and that result will be wrong. Whether it&#x27;s from cosmic rays resetting bits in memory, or multiple cosmic ray strikes resetting multiple bits and thus defeating ECC, sooner or later things will break no matter what you do. Even if you shield all the computers with 5 meters of pre-nuclear age lead, eventually it will break.<p>The point is that it is just not possible to get to perfect reliability. Your actual reliability is always going to be less than 100%. You can invest money and effort to get closer to 100%, but obviously you are going to get diminishing returns.<p>The correct analysis is to decide where the optimal trade-off is between investing in reliability and the return on that investment.<p>Example 1: You are calling a web service that checks the weather. The service might be down. If it is down you wait a few seconds and try it again. The &#x27;cost&#x27; of it being down is that a user doesn&#x27;t see the current weather. Is it worthwhile to carefully try to determine whether the error when calling the service is due to a server returning a 500 status code versus invalid json?<p>No, it&#x27;s not worth it. Either way the client can&#x27;t use the response. In fact, it doesn&#x27;t matter what causes the exception, since anything that goes wrong can&#x27;t be corrected by the client. Whether it&#x27;s bad json, a network failure, dns failure, the server is being rebooted, the webserver is misconfigured, or the device is in airplane mode, the resolution is always the same, wait and try again in a few seconds. Exceptions work pretty much ideally in this case, you only have to code the &#x27;happy&#x27; path and handle all exceptions the same way generically.<p>Example 2: You are writing code to update a database containing financial transactions. If something goes wrong in an unexpected way you need to make sure the financial data isn&#x27;t updated or left partially updated.<p>Again, you don&#x27;t care about unexpected exceptions. For failures you expect and are coding to work around them, possibly by catching the generic exception where it happens deep in the call stack, and then raising your own exception class which properly identifies the error and contains the context necessary to perform the recovery. For example, if you need to send an email via receipt for the transaction, you call some function which formats and sends the email. That function fails due to the email server being unreachable. The network exception is caught and an EmailCantBeSent exception is raised with the relevant details in it (the user_id you were emailing, the transaction_id the email is for). The resolution is to log a critical error and insert a record to the database with the relevant details of the email so that someone can make sure it is sent later. Then it continues with the transaction. If something unexpected happens the database transaction is never committed.<p>My point is that there are two kinds of exceptions you run into, the ones you are being careful to trap and resolve as part of your applications design, and the ones that you aren&#x27;t trying to resolve and so result in just a generic &#x27;this failed&#x27; situation.<p>So finally getting back to finding the optimal tradeoff between investment to improve reliability and payback on that investment, you just need to make sure your generic failures are rare enough that you aren&#x27;t pushed far from that optimal point, which is almost always going to be the case, even if you basically don&#x27;t ever handle any exceptions and only code for the happy path. Obviously there are tons of counter-examples and sometimes you need to make sure things work even when something goes wrong (if you are working on an autopilot you will require much higher reliability and so much more careful planning to reach it compared to a twitter client, where you just need to not lose what the person typed).<p>Ok that&#x27;s a lot longer than I intended.<p>TLDR; If you do any kind of analysis on why code fails and what you should do about that, you quickly realize that this library doesn&#x27;t help at all. This library isn&#x27;t even bad, the problem it is meant to solve is not well posed.
PaulHouleover 6 years ago
&quot;X considered harmful&quot;<p>&quot;X&quot; implies &quot;X considered harmful&quot;<p>Thus<p>&quot;X considered harmful&quot; considered harmful<p>&quot;&#x27;X considered harmful&#x27; considered harmful&quot; considered harmful<p>...<p>QED
评论 #19146658 未加载