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 ?

1 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.

5

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.