5

Someone recently said to me "In Python it is better to try and ask for forgiveness later instead of begging for permission" which I found quite funny but also relates to my question

I'm creating a personal assistant of sorts called Ada and was being pedantic about performance. From what I gather, using a try statement is faster when it works then checking and then executing. E.G: (The second one being slower if the directory DOESNT EXIST???)

import os

try:
    os.makedirs("Test")
except FileExistsError:
    pass

# VS

if not os.path.exists("Test"):
    os.makedirs("Test")

So when creating coding, you need to weigh up whats more likely. In my example it would be the file is more likely to NOT exist so I should use a try block which yields better performance then an If-Else

I was wondering if this is of any benefit to try (pun intended) this method of the default If-Else?

P.S (This question isn't a duplicate of Python if vs try-except since that's not specifying about comparing the probabilities of the try: code block)

My current code if anyone's interested: (Created a folder in AppData called Ada where a Config.ini file is made)

import os

AppDataDirectory = os.getenv("AppData")
AdaDirectory = AppDataDirectory + "\Ada"
ConfigFile = AdaDirectory + "\CONFIG.ini"

try:
    File = open(ConfigFile, "r")
except FileNotFoundError:
    try:
        os.makedirs(AdaDirectory)
    except FileExistsError:
        print("Config File Missing")
    # Setup Config File
DAda
  • 947
  • 1
  • 5
  • 6
  • Unless you are going to be performing this operation *a lot*, I wouldn't think the performance difference would be worth worrying about, and should instead focus on making the code clear. – Scott Hunter Dec 03 '20 at 17:25
  • @ScottHunter Ah performance is more important to me then clarity or readability of code – DAda Dec 03 '20 at 17:26
  • Then you should be profiling it. – Scott Hunter Dec 03 '20 at 17:32
  • Does this answer your question? [How can you profile a Python script?](https://stackoverflow.com/questions/582336/how-can-you-profile-a-python-script) – Random Davis Dec 03 '20 at 17:33
  • 1
    I'd say using `try-except` blocks instead of `if-else` blocks is a bad idea. Even considering the performance overhead, it will never cause even a remotely significant difference. – P S Solanki Dec 03 '20 at 17:35
  • In general, `try-except` blocks can't replace `if-else` functionality. Exception handling is meant to handle `exceptions`, not to handle different scenarios. This should be specifically considered in cases where a `try` block has multiple statements. If an `exception` is raised in the very last statement of that block, the piece of code till that statement would have been executed and you wouldn't know what exactly happened in the code 'cause it won't tell you as you'll `catch` the exception right after it gets raised. – P S Solanki Dec 03 '20 at 17:46
  • @PSSolanki but for one line pieces of code that make files/directories its fine? – DAda Dec 03 '20 at 17:57
  • 1
    Try except is faster if you stay out of except most of the time. If your file is quite likely to be missing then it will be slower, possibly significantly so. Exception handling is costly, basically. There was a podcast recently in either Python Bytes or Talk Python to me that detailed precisely this. If you’re not ignoring Knuth about premature optimization, then profile your use case, *including present/missing ratios*, rather than asking here. – JL Peyret Dec 03 '20 at 22:05
  • It's still not recommended. As @JLPeyret said. If you still think it would be a considerable choice in your use case, profile your code. compare results. – P S Solanki Dec 04 '20 at 05:47

2 Answers2

0

The performance of try vs. if-else depends.

Generally, it is considered more pythonic to use try blocks because:

  1. You do an action
  2. If it fails then do something else

The benefit here is that if the action fails you can specify an exact error and react accordingly or keep the exception at the Base Exception class.

Using if-else isn't necessarily non-pythonic but with them python (this gets longer if there are elif statements),

  1. Checks the boolean value of a statement
  2. If boolean value is desired, then perform another action
  3. If boolean value is not desired then do something else

Ultimately try blocks are recommended because you do something and specify an exact response if the action fails as opposed to setting up a variety of conditions.

swagless_monk
  • 441
  • 6
  • 21
0

A real time use case example of try-catch && if-else with Django: I created a custom user model in account app. So if i try to import it from default user model like.

from django.contrib.auth.models import User

I will get a error like:

AttributeError: Manager isn't available; 'auth.User' has been swapped for 'account.User

and this will hang the process.

#from account.models import User # this is the correct import
if User.objects.filter(username="milon").exits():
    print(f"Super User with username {env('SUPER_USER_NAME')} is already exit!!")
else:
    superuser = User.objects.create_superuser(
        username="milon", email="alim.abdul@gmail.com", password="******")
    superuser.save()

But if I use try-catch block.

try:
    superuser = User.objects.create_superuser(
        username="milon"), email="alim.abdul@gmail.com", password="******")
    superuser.save()
except IntegrityError:
    print(f"Super User with username {env('SUPER_USER_NAME')} is already exit!!")
except Exception as e:
    print(e)

We will get bellow error and this will not hang the process.

Manager isn't available; 'auth.User' has been swapped for 'account.User'

This example was tried in docker where i was used django & react separate project in docker container. For if-else docker was hanged the other processes. But using try-catch others process was not hanged in docker container.

abdulalim
  • 430
  • 5
  • 9