Python Coding Style Guide: Best Practices and Conventions
This comprehensive guide explains Python coding style best practices, covering PEP 8 extensions, flexible line length, naming conventions, docstring standards, functional versus object‑oriented design, testing, standard library usage, third‑party tools, and project structure to produce readable, maintainable code.
The article expands beyond PEP 8 to propose a pragmatic Python style that balances strict guidelines with flexibility, emphasizing readability, maintainability, and sensible defaults.
Line length flexibility : While 79‑character lines are a good rule of thumb, flake8’s max-line-length can be adjusted or ignored with # noqa when necessary.
Naming conventions (derived from the Pocoo team):
Class names: CapWords, e.g., class HTTPWriter(object):
Variable names: lowercase_with_underscores
Method/function names: lowercase_with_underscores
Modules: lowercase_without_underscores, e.g., my_module.py
Constants: UPPERCASE_WITH_UNDERSCORES
Pre‑compiled regexes: pattern_re
Avoid leading/trailing underscores except for private names ( _private ) and name clashes with built‑ins ( sum_ = sum(some_long_list) ).
Self‑parameter conventions :
Instance methods: first argument self
Class methods: first argument cls
Variadic arguments: *args and **kwargs
Prefer functions over classes for most reusable code; use classes only when they provide a clear benefit such as custom containers or descriptors.
Generators and iterators are highlighted as powerful tools; learn the iterator protocol, yield , and generator expressions (e.g., sum(x for x in items if x > 0) ).
Docstrings should be a single concise sentence, use triple quotes on one line, start with a capital letter, end with a period, and follow reST conventions for parameters and return types (see def get(url, qsargs=None, timeout=5.0): example).
Code style examples (good vs. bad):
# Bad class inheritance (Python 2)
class JSONWriter:
pass
# Good (Python 2) – inherit from object
class JSONWriter(object):
pass # Bad use of backslashes for line continuation
response = Search(using=client) \
.filter("term", cat="search") \
.query("match", title="python")
# Good – wrap in parentheses
response = (Search(using=client)
.filter("term", cat="search")
.query("match", title="python")) # Bad list building
filtered = []
for x in items:
if x.endswith('.py'):
filtered.append(x)
return filtered
# Good – list comprehension
return [x for x in items if x.endswith('.py')]Exception handling : Prefer specific except clauses, avoid bare except: pass , and use the logging module for error reporting.
Testing is essential; write unit tests with pytest , mock , or hypothesis to ensure code correctness.
Standard library and common third‑party tools :
import datetime as dt and use dt.datetime.utcnow()
import json for data exchange
from collections import namedtuple, defaultdict, deque
from itertools import groupby, chain
from functools import wraps
import argparse for CLI utilities
import logging with log = logging.getLogger(__name__)
Popular third‑party libraries include python-dateutil , pytz , tldextract , msgpack , futures , docopt , and pytest .
Project layout recommendations :
Root package without __init__.py (folder name is the package)
Prefer mypackage/__init__.py over src/mypackage/__init__.py
Place settings in mypackage/settings.py
Include README.rst , setup.py , requirements.txt , and a simple Makefile for build, lint, test, and run steps
Overall, the guide advocates “beautiful over ugly”, “explicit over implicit”, and “flat over nested” code structures, encouraging developers to write clear, well‑documented, and testable Python code.
Qunar Tech Salon
Qunar Tech Salon is a learning and exchange platform for Qunar engineers and industry peers. We share cutting-edge technology trends and topics, providing a free platform for mid-to-senior technical professionals to exchange and learn.
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.