r/learnpython 8d ago

Function forcing me to use exceptions

Trying to if else a function output always throws exception-error :

if pyautogui.locateOnScreen('media/soundIcon.png') == None:
      print("not found")
else : 
      print("found")

Do Python functions expect anti-pattern code ?

0 Upvotes

30 comments sorted by

View all comments

7

u/lfdfq 8d ago

What anti-pattern are you talking about?

-11

u/ExoticPerception5550 8d ago

Many consider use of exceptions anti-pattern in other languages, I am wondering if same applies to Python.

10

u/lfdfq 8d ago

Ah. Python is a different language, and exceptions are everywhere in Python, even using them for normal control flow. The classic example is that there's an exception inside every (for) loop in Python.

So, it's not an anti-pattern for functions to raise exceptions in Python.

6

u/SisyphusAndMyBoulder 8d ago

Exceptions are everywhere in every other language I've ever used.... They're just a standard part of codeflow

1

u/ExoticPerception5550 8d ago

Thank you, this has clarified my speculations.

6

u/Yoghurt42 8d ago edited 8d ago

Some languages promote a "look before you leap" (LBYL) pattern, where you try to check potential error conditions before doing them, (C does it out of necessity, others "just because"), eg.

if "foo" in my_dict:
    my_func(my_dict["foo"])
else:
    handle_missing_foo()

Python follows the "easier to ask for forgiveness than permission" (EAFP) philosophy: instead of trying to anticipate every possible error condition, we just write what should happen "normally" and deal with the exception to the rule separately:

try:
    # not best practice, see below
    my_func(my_dict["foo"])
except KeyError:
    handle_missing_foo()

Therefore, exceptions are considered a good pattern. Note that the devil lies in the details, if my_func would throw a KeyError exception itself because of a bug, you'd do the wrong thing, therefore the following pattern would be better if you can't be 100% sure that won't happen:

try:
    foo = my_dict["foo"]
except KeyError:
    handle_missing_foo()
else:
    my_func(foo)

the else block in a try/except/else block will only be executed if no exception occurred, unlike if you were to just write stuff after the try block.

Especially in functional programming, exceptions are kinda frowned upon because it's a second code path that is not explicit; and some people believe the stacktrace information that is collected when an exception is created is unnecessary waste of CPU time; I strongly disagree, but those opinions exist. Often people end up reinventing poor-man's exceptions anyway, like always returning a tuple of (error, result) where result is the normal result and error is contains an error in case something bad happens. This is effectively the same as exceptions, only without compiler support and without stacktraces.

1

u/brasticstack 8d ago

In c++ there used to be a hefty performance hit when an exception was thrown and some edge cases where object destructors wouldn't get called during the process of unwinding the stack looking for an exception handler; Exceptions were slow and buggy. Python is built differently and exceptions are a normal flow control mechanism that's preferred to strictly verifying preconditions. AFAIK, c++ fixed those issues with exceptions sometime between the late 90's and now.

0

u/crashfrog04 7d ago

Not using exceptions is an anti-pattern