Best Practices in Python
This article explains best practices in Python.
We will explain Python best practices with actual code samples, introducing ways to write readable and maintainable code.
YouTube Video
Best Practices in Python
Make readability the top priority
First, let's look at 'making readability the top priority.'.
Python is a language that values 'readability.'. First, prioritize writing code whose intention is clear at a glance.
1# Bad example: unclear variable names
2a = 10
3b = 5
4c = a * bIn this code, variable names do not convey their meaning, so it takes time for others to understand it later.
1# Good example: descriptive variable names
2price = 10
3quantity = 5
4total_cost = price * quantityBy making variable names specific, your code itself serves as documentation.
Write explicit code
Next, let's look at 'writing explicit code.'.
In Python, 'explicit intention' is preferred over 'implicit behavior.'.
1# Bad example: implicit truthy check
2if data:
3 process(data)In this code, it is unclear what is expected of data, creating fertile ground for bugs.
1# Good example: explicit condition
2if len(data) > 0:
3 process(data)By making conditions explicit, the code's intent matches its specification.
Keep functions small and focused on a single responsibility
Next, let's look at 'keeping functions small and focused on a single responsibility.'.
When one function does too many things, testing and maintenance become difficult.
1# Bad example: doing too many things
2def handle_user(user):
3 save_to_database(user)
4 send_email(user)
5 write_log(user)In this code, processes become tightly coupled, making reuse and modification difficult.
1# Good example: single responsibility
2def save_user(user):
3 save_to_database(user)
4
5def notify_user(user):
6 send_email(user)
7
8def log_user(user):
9 write_log(user)By splitting functions, their roles become clear and testing becomes easier.
Actively use type hints
Next, let's look at 'actively using type hints.'.
Type hints serve as documentation and are a powerful tool to prevent bugs.
1# Bad example: Without type hints
2def add(a, b):
3 return a + bIn this code, the types of arguments and return values are unclear, making misuse likely.
1# Good example: With type hints
2def add(a: int, b: int) -> int:
3 return a + bWith type hints, IDE completion, static analysis, and readability greatly improve.
Explicitly indicate the possibility of returning None
Next, let's look at 'explicitly indicating the possibility of returning None.'.
Functions that may return None are often overlooked by those who use them.
1# Bad example: Ambiguous return value
2def find_user(user_id):
3 if user_id == 1:
4 return {"id": 1, "name": "Alice"}
5 return NoneIn this code, it is unclear whether there will be a return value.
1# Good example: explicit return type
2from typing import Optional, Dict, Any
3
4def find_user(user_id: int) -> Optional[Dict[str, Any]]:
5 if user_id == 1:
6 return {"id": 1, "name": "Alice"}
7 return NoneBy using Optional, you can convey the possibility of returning None as a type.
Do not catch exceptions too broadly
Next, let's look at 'not catching exceptions too broadly.'.
Exception handling should basically catch only what is necessary.
1# Bad example: catching all exceptions
2try:
3 result = int(value)
4except Exception:
5 result = 0This code may hide bugs that should have been noticed.
1# Good example: catch specific exception
2try:
3 result = int(value)
4except ValueError:
5 result = 0By restricting exceptions, you will not overlook unexpected issues.
Safely handle resources with the with statement
Next, let's look at 'safely handling resources with the with statement.'.
Resources such as files and locks must always be reliably released.
1# Bad example: manual close
2file = open("data.txt")
3content = file.read()
4file.close()In this code, if an exception occurs, close() may not be called.
1# Good example: using context manager
2with open("data.txt") as file:
3 content = file.read()By using a with statement, cleanup is safely performed even if an exception occurs.
Use list comprehensions appropriately
Next, let's look at 'appropriately using list comprehensions.'.
Simple transformation processes can be written concisely using list comprehensions.
1# Bad example: Verbose loop
2squares = []
3for i in range(10):
4 squares.append(i * i)In this code, the core process is hard to see.
1# Good example: Clear list comprehension
2squares = [i * i for i in range(10)]By using list comprehensions appropriately, code readability improves.
Avoid magic numbers
Next, let's look at 'avoiding magic numbers.'.
Writing numbers and strings directly makes their meaning unclear.
1# Bad example: magic number
2if status == 404:
3 handle_not_found()In this code, it is assumed that you know the meaning of 404.
1# Good example: named constant
2NOT_FOUND = 404
3
4if status == NOT_FOUND:
5 handle_not_found()Giving names makes intentions clear.
Write code that is maintainable, not just code that 'works'
Finally, let's look at 'writing code that is maintainable, not just code that works.'.
The important point is whether your future self or others can read it.
1# Bad example: Hard to maintain
2def f(x):
3 return x * 1.08 + 100In this code, the specification cannot be understood from the code.
1# Good example: Easy to maintain
2TAX_RATE = 1.08
3BASE_FEE = 100
4
5def calculate_total(price: float) -> float:
6 return price * TAX_RATE + BASE_FEEBy reflecting meaning in names, the code itself becomes the specification.
Summary
Python best practices boil down to writing code that is easy to understand, rather than clever code. Building small habits leads to code with fewer bugs that can be used for a long time.
You can follow along with the above article using Visual Studio Code on our YouTube channel. Please also check out the YouTube channel.