Python Best Practices: Reducing Numeric Literals, Using Enums, and Writing Cleaner Code
This article presents practical Python best‑practice guidelines, including avoiding hard‑coded numeric literals by using enums, limiting raw string manipulation in favor of object‑oriented query building, keeping literal expressions readable, and applying useful tips such as treating booleans as numbers, handling long strings, using infinity constants, and understanding thread‑safety and string‑concatenation performance.
Numbers are the most basic data type in almost every programming language, and Python provides three numeric types: int , float , and complex . While integers are safe and unbounded, floating‑point numbers suffer from precision issues that often confuse beginners.
Beyond numbers, strings in Python are more complex; understanding the difference between bytes and str and migrating from Python 2 to Python 3 are essential steps before diving into advanced topics.
Best Practices
1. Avoid Hard‑Coded Numeric Literals
Numeric literals appear everywhere, such as delusers[0] . When the same literal repeats, it signals a potential code‑quality warning. For example:
<code>def mark_trip_as_featured(trip):
"""Add a trip to the featured column"""
if trip.source == 11:
do_some_thing(trip)
elif trip.source == 12:
do_some_other_thing(trip)
...
return</code>Replacing the magic numbers with an Enum improves readability and reduces bugs:
<code># -*- coding: utf-8 -*-
from enum import IntEnum
class TripSource(IntEnum):
FROM_WEBSITE = 11
FROM_IOS_CLIENT = 12
def mark_trip_as_featured(trip):
if trip.source == TripSource.FROM_WEBSITE:
do_some_thing(trip)
elif trip.source == TripSource.FROM_IOS_CLIENT:
do_some_other_thing(trip)
...
return</code>Using enums makes the code self‑documenting and prevents accidental typos such as writing 111 instead of 11 .
2. Don’t Over‑Process Bare Strings
When building SQL or other structured strings, prefer object‑oriented builders (e.g., SQLAlchemy) over manual concatenation:
<code>def fetch_users(conn, min_level=None, gender=None, has_membership=False, sort_field="created"):
statement = "SELECT id, name FROM users WHERE 1=1"
params = []
if min_level is not None:
statement += " AND level >= ?"
params.append(min_level)
if gender is not None:
statement += " AND gender >= ?"
params.append(gender)
if has_membership:
statement += " AND has_membership == true"
else:
statement += " AND has_membership == false"
statement += " ORDER BY ?"
params.append(sort_field)
return list(conn.execute(statement, params))
</code>The same logic using SQLAlchemy is shorter, safer, and avoids SQL‑injection risks:
<code>def fetch_users_v2(conn, min_level=None, gender=None, has_membership=False, sort_field="created"):
query = select([users.c.id, users.c.name])
if min_level is not None:
query = query.where(users.c.level >= min_level)
if gender is not None:
query = query.where(users.c.gender == gender)
query = query.where(users.c.has_membership == has_membership).order_by(users.c[sort_field])
return list(conn.execute(query))
</code>3. Keep Literal Expressions Intact
Pre‑computing constant expressions (e.g., 950400 for 11 days in seconds) offers no performance benefit because Python’s compiler already folds them. Writing the expression directly improves readability:
<code>def f1(delta_seconds):
if delta_seconds < 11*24*3600:
...
</code>Disassembly shows the multiplication is performed at compile time, so there is no runtime cost.
Practical Tips
1. Booleans Are Also Numbers
In Python, True equals 1 and False equals 0 , which can simplify calculations with sum or list indexing.
2. Improve Long‑String Readability
Wrap long strings in parentheses to split them across lines, or use textwrap.dedent for multi‑line literals inside indented blocks.
3. Use Right‑to‑Left String Methods
Methods prefixed with r (e.g., rsplit ) process from the end, making tasks like extracting the last token from a log line simpler.
4. Use Infinity Constants
float("inf") and float("-inf") represent positive and negative infinity, useful for initializing comparison variables.
Common Misconceptions
1. value += 1 Is Not Thread‑Safe
Bytecode shows that value += 1 compiles to multiple steps ( LOAD_FAST , INPLACE_ADD , STORE_FAST ), which can be interleaved by other threads, leading to race conditions.
2. String Concatenation Is Not Slow Anymore
Since Python 2.3, the interpreter optimizes += concatenation, making it comparable in speed to "".join() for most use cases.
*Disclaimer: This article is compiled from online sources; copyright belongs to the original author.*
Python Programming Learning Circle
A global community of Chinese Python developers offering technical articles, columns, original video tutorials, and problem sets. Topics include web full‑stack development, web scraping, data analysis, natural language processing, image processing, machine learning, automated testing, DevOps automation, and big data.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.