Pythonic style, performance & next steps
PEP 8 and idioms, measuring and improving performance, maintainable code and career paths after this course.
Congratulations — you've covered the full journey from print("Hello") to web APIs, databases and packaging. This final lesson is about craft: writing code that other Python developers immediately recognise as clean and idiomatic ("Pythonic"), making it fast where it matters, and planning what to learn next on your way to a Python job.
The Zen of Python#
Type import this in the REPL:
"Readability counts" is the heart of it. Code is read far more often than it's written — by teammates, reviewers and future you.
PEP 8 in a nutshell#
PEP 8 is the official style guide. The essentials:
- Indentation: 4 spaces, never tabs.
- Line length: 79 is the classic limit; many teams use 88–100. Be consistent.
- Naming:
snake_casefor functions, variables and modules;PascalCasefor classes;UPPER_SNAKE_CASEfor constants; a leading_for internal names. - Imports: at the top, one per line, grouped standard library / third-party / local.
- Whitespace: spaces around operators and after commas (
x = a + b,f(a, b)), none inside brackets; two blank lines between top-level functions and classes. - Comparisons:
if x is None,if not items,if isinstance(x, int)— not== None,len(items) == 0ortype(x) == int.
Don't format by hand — let a tool do it. ruff checks style and common bugs, and ruff format (or black) rewrites your code consistently:
Pythonic idioms#
Each pair below does the same job; the second version is what experienced Python developers write.
More idioms worth adopting:
A few more principles:
- EAFP: try the operation and handle the exception, rather than checking every precondition first.
- Return early with guard clauses instead of deep nesting.
- Small functions with clear names beat comments explaining long ones.
- Don't over-engineer: not everything needs a class; a function or a dict is often enough.
- Use the standard library before writing helpers or adding dependencies.
Performance: measure first#
"Premature optimisation is the root of all evil." Write clear code first; then, if it's too slow, measure to find the real bottleneck. timeit compares small snippets:
For whole programs, use the built-in profiler to see which functions take the time:
The optimisations that actually matter
- Better algorithms and data structures. This dwarfs every micro-trick. Membership tests in a
setordictinstead of a list turn O(n²) loops into O(n):
- Use built-ins and the standard library —
sum,min,max,sorted,str.join,collections,itertools— they run in C. - Vectorise numeric work with NumPy/pandas instead of Python loops.
- Avoid repeated work: hoist invariant computations out of loops, cache expensive pure functions with
functools.cache. - Stream large data with generators instead of building giant lists.
- Concurrency for I/O-bound waits (threads/asyncio) and processes for CPU-bound work.
- Upgrade Python: 3.11 was 10–60% faster than 3.10, and each release since has added more speed-ups.
Beyond that there are specialised tools — PyPy (a JIT-compiled Python), Cython, Numba, or writing hot paths in Rust with PyO3 — but most real-world slowness is fixed by points 1–5.
Writing maintainable code#
- Type hints + mypy/pyright on public functions.
- Tests for behaviour, run automatically in CI.
- Docstrings for public modules, classes and functions; comments explain why, not what.
- Logging, not print, in applications.
- Configuration from the environment; no secrets in code.
- Small, focused commits and pull requests with clear descriptions.
Where to go next#
You now have a complete foundation. Python careers branch in a few directions — pick one that excites you and build projects in it:
Some practical advice:
- Build projects, not just tutorials. A to-do API, a web scraper that emails you price drops, a CLI that organises your downloads, a dashboard of your expenses. Put them on GitHub with a README and tests.
- Read good code: the standard library source, popular projects like
requests,richorhttpx. - Practice problem-solving on sites like LeetCode, HackerRank or Exercism for interview preparation — data structures and algorithms questions come up often.
- Contribute to open source: start with documentation fixes or issues labelled "good first issue".
- Keep up with releases: skim "What's New in Python 3.x" each October.
- Explore Elephantoo's other courses — MySQL, Linux and JavaScript pair naturally with Python in almost every job.
A final checklist#
Before you call a Python project "done", check that it:
- runs in a fresh virtual environment from
pyproject.toml/requirements.txt - passes
ruff check,ruff format --checkand a type checker - has tests for its core behaviour, passing in CI
- handles errors with specific exceptions and useful messages
- logs instead of printing, and keeps secrets out of the code
- has a README explaining what it does and how to run it
Common mistakes#
- Optimising before measuring.
- Clever one-liners that nobody (including you, next month) can read.
- Ignoring linters and type checkers — they catch real bugs for free.
- Endless tutorial-watching without building anything of your own.
- Trying to learn every library — depth in the fundamentals beats shallow familiarity with everything.
What's next#
That's the end of the Python course — well done! Revisit any lesson's quiz to check your understanding, then start building. Happy coding! 🐘
Check your understanding
Quick quiz
1.According to PEP 8, how should a function that calculates a total be named?
2.You need to check membership many times against 100,000 IDs. Which structure should hold the IDs?
3.What is the first step when your program is too slow?
Finished reading?
Mark this lesson complete to track your progress.