Things I Wish Someone Had Explained To Me Sooner About Python
Episode Deep Dive
Guest Introduction and Background
Jason McDonald is a Python developer, speaker, author, and long-standing community member best known for his book Dead Simple Python. He discovered his affinity for coding after a life-changing accident derailed his original plans of going into medicine, leading him to explore software development as a new path. Through self-study in VB.NET and eventually Python, Jason found a language and community that matched his passion for creating games and educational tools. Today, he’s heavily involved in the Python ecosystem—working on backend projects with FastAPI, SQLAlchemy, and other libraries, while also advocating for strong coding fundamentals and mentorship. Jason’s journey from hard knocks and self-teaching to publishing a comprehensive Python book gives him a relatable yet deeply knowledgeable perspective on what new and seasoned developers truly need to know.
What to Know If You're New to Python
Learning Python can feel overwhelming at first, but this episode highlights the concepts that matter most—like understanding variables, references, duck typing, and virtual environments. By getting these fundamentals right, you’ll save yourself hours of frustration and refactoring. Having a clear sense of how Python handles data under the hood is crucial to writing efficient and reliable code. Make a point to experiment with small projects that help you explore these deeper Python features.
Key Points and Takeaways
- Core Mental Model of Python Variables This episode stresses that Python’s variables work differently than in many other languages. Rather than tying a type to a variable, Python ties types to objects themselves, while variables act more like labels pointing to those objects. This difference means you must be mindful when modifying mutable objects (like lists and dictionaries) since multiple variables could reference the same item. Being aware of Python’s naming and references also informs how you structure functions, how you pass data around, and how you think about memory usage. Understanding this variable-model shift is the foundation of writing clear, bug-free Python.
- Relevant Links & Tools:
- Python Docs on Variables and Namespaces
- Example talk on references by Ned Batchelder
- Relevant Links & Tools:
- Embracing Duck Typing Duck typing means Python cares about what an object can do (its methods and properties) rather than strictly what it is (the class or type). This encourages simpler inheritance patterns and, in many cases, removes the need for complex interfaces. When you call a function that expects “file-like” behavior, for instance, any object with a
.read()
method could work—no explicit inheritance chain required. Duck typing keeps Python code flexible, easy to extend, and often more readable. However, it also means you must write clear documentation (or use type hints) to help others understand the intended usage.- Relevant Links & Tools:
- Pydantic: pydantic-docs.helpmanual.io (Great for validating object structure even in a duck-typed environment)
- Python Docs on Abstract Base Classes
- Relevant Links & Tools:
- Going Deeper with Iteration and Comprehensions Python’s iteration model unlocks many possibilities, including lazy loading large data sets or breaking problems into smaller chunks with generators. List comprehensions, set comprehensions, and generator expressions let you turn many-loop operations into concise, powerful one-liners. Although they can be more performant and readable than manual loops, using them excessively or nesting them deeply can hinder clarity. The conversation also highlights the power of libraries like
itertools
—showing how you can elegantly generate permutations, combinations, or even infinite sequences. Understanding these iteration tools helps you write more Pythonic, performant code when scanning through collections or computing results on the fly.- Relevant Links & Tools:
- itertools (Part of the standard library)
- PEP 709 (Inline Comprehensions PR)
- Relevant Links & Tools:
- Setting Up Virtual Environments from Day One Virtual environments lie at the heart of Python development best practices and help isolate project dependencies. Instead of installing packages system-wide and risking conflicts,
venv
or tools likepipenv
let you manage unique sets of packages per project. The transcript underscores how simple it is to create these environments and keep them up-to-date, preventing the dreaded “works on my machine” problem. The key is integratingvenv
usage into your workflow early, whether that’s via aliases, shell scripts, or IDE support. Once you’re comfortable with them, you’ll never go back to installing everything globally. - Importance of Packaging and Project Structure Jason recommends setting up packaging as soon as you start a project, rather than waiting until the end. Proper packaging ensures your code is installed and run the same way users will experience it, including how dependencies are handled. Running tests outside your source folder mimics real-world usage and exposes packaging or dependency issues early. Tools like
pyproject.toml
and the standard packaging libraries help streamline versioning and distribution, making it simpler to share or deploy your work. Proper structuring and packaging from day one leads to maintainable, professional-grade Python applications.- Relevant Links & Tools:
- Concurrency vs. Parallelism This conversation clarifies that concurrency and parallelism are distinct. Concurrency involves interleaving tasks (like switching between them quickly), whereas parallelism truly executes tasks simultaneously on multiple CPU cores. Python’s Global Interpreter Lock (GIL) impacts how threads share CPU time, often making concurrency more useful for IO-bound tasks. For CPU-bound tasks, you might turn to multi-processing to break free of the GIL. Understanding this difference lets you pick the correct approach for your project, ensuring optimal performance without overcomplicating your code.
- Relevant Links & Tools:
- Async and Await Made Approachable Despite perceptions that async programming is too advanced, Jason and Michael emphasize that
async
andawait
in Python make many concurrent tasks straightforward. Asynchronous code can shine for network requests and other wait-oriented operations, letting you handle multiple tasks while waiting on external resources. This structure is more predictable than managing threads explicitly in many situations. Modern frameworks like FastAPI leverage async/await for quick, high-performance APIs that can handle numerous requests. Embracing async requires a small conceptual shift, but most folks find it more intuitive than juggling threads once they see it in action. - Practical Examples for Concurrency and Testing Jason delves into creating real examples that illustrate concurrency beyond the trivial “fetch data from a URL” scenario. He highlights how concurrency can be used for iterative tasks like data analysis, user interaction, or even multi-step processes where one step depends on another. Proper concurrency or parallelism eliminates idle CPU or user-wait times and ensures better throughput in applications. However, each method, whether it’s threading or multiprocessing, brings trade-offs like overhead and complexity. Hands-on examples and thorough testing (with frameworks such as
pytest
) are essential to confirm that your concurrency approach is correct and free of data races.- Relevant Links & Tools:
- Refactoring, Readability, and ‘Dead Simple Python’ Jason’s own code evolution taught him that “if it works” is not enough; clarity, structure, and Pythonic idioms make code more maintainable. In his book Dead Simple Python, he shares how understanding the why behind each Python feature leads to more elegant solutions. Refactoring typically goes smoother when code is laid out with logical modules, smaller functions, and consistent naming. He also notes that list comprehensions, context managers, and concurrency patterns become more approachable with a firm grasp on Python’s internals. Overall, a clean, Pythonic style saves time during both development and maintenance.
- Relevant Links & Tools:
- Dead Simple Python by Jason McDonald: No Starch Press
- Flake8 or black for code consistency
- Relevant Links & Tools:
- Favorite Libraries: Hypothesis and Branch Detective Hypothesis is highlighted as a game-changer for testing in Python, automatically searching for edge cases and simplifying test-driven development. It uses property-based testing to generate and reduce failing examples, often discovering bugs that conventional tests miss. Meanwhile, Jason’s own “Branch Detective” library helps compare commits across divergent Git branches, tackling complexities around cherry picks and merges. Both tools illustrate how Python’s ecosystem thrives on creative and powerful libraries. They also show that building tools to solve real development pain points is a key strength of open-source communities.
- Relevant Links & Tools:
Interesting Quotes and Stories
- “I fell down a staircase, hit my head, and ended all hopes of becoming a doctor. That’s how I discovered I had a knack for coding.” — Jason, sharing his unexpected start in software.
- “A lot of these advanced Python concepts look intimidating from the outside, but once you see them, it’s like ‘why did I wait so long to learn it?’”
- “Duck typing doesn’t care about who your parent class is, just that you quack like a duck.”
- “Packaging from day one? It’s the difference between two days of coding and two years of trying to fix your distribution later.”
- “A concurrency approach won’t make your single function run faster, but while you’re waiting on something, you can get something else done.”
Key Definitions and Terms
- Duck Typing: A style of dynamic typing in Python where an object’s actual class is less important than the methods and properties it defines.
- GIL (Global Interpreter Lock): A mechanism in the CPython runtime allowing only one thread at a time to execute Python bytecode, affecting parallel execution of CPU-bound code.
- Async/Await: Language keywords in Python that enable asynchronous programming, allowing functions to pause and resume while waiting for IO operations.
- Virtual Environment: An isolated Python environment that keeps dependencies separated and avoids conflicts with system-wide or other project installations.
- Property-Based Testing: A testing method (exemplified by the
Hypothesis
library) where tests define general properties of input data, and the tool automatically generates test cases.
Learning Resources
Here are a few places you can go deeper into Python’s concurrency patterns, testing strategies, and overall best practices:
- Async Techniques and Examples in Python Focused on multiprocessing, threading, and async/await tips that mesh perfectly with the concurrency topics from this episode.
- Modern APIs with FastAPI and Python If the async/await approach piques your interest, you’ll learn all about building lightning-fast APIs using the latest Python 3 features.
Overall Takeaway
This episode underscores the importance of gaining a real understanding of Python’s internals and development workflows—from how variables truly work, to structuring projects for success, to deciding whether concurrency or parallelism suits your needs. Jason’s journey and insights highlight that advanced Python concepts are often less daunting than we imagine, especially once we see them in action. By embracing best practices early—like virtual environments, packaging, and Pythonic code structures—you’ll reduce technical debt and build far more maintainable applications. Moreover, exploring libraries such as Hypothesis, as well as concurrency frameworks like asyncio and FastAPI, can level up your programming game significantly. Ultimately, investing time to understand these Python fundamentals pays huge dividends and ensures you’ll thrive in both simple scripts and sophisticated software projects.
Links from the show
Dead Simple Python: nostarch.com
Coroutines and Tasks: docs.python.org
Duck Typing: wikipedia.org
Static Duck Typing in Python with Protocols: daan.fyi
PEP 709: peps.python.org
PEP 289: peps.python.org
Python Packaging Strategy Discussion - Part 1: discuss.python.org
Branch-detective: github.com
Hypothesis: readthedocs.io
Pydantic v2 announcement: pydantic.dev
Michael's venv alias: digitaloceanspaces.com
Watch this episode on YouTube: youtube.com
Episode transcripts: talkpython.fm
--- Stay in touch with us ---
Subscribe to Talk Python on YouTube: youtube.com
Talk Python on Bluesky: @talkpython.fm at bsky.app
Talk Python on Mastodon: talkpython
Michael on Bluesky: @mkennedy.codes at bsky.app
Michael on Mastodon: mkennedy