Learn Python with Talk Python's 270 hours of courses

Things I Wish Someone Had Explained To Me Sooner About Python

Episode #411, published Fri, Apr 14, 2023, recorded Thu, Mar 2, 2023

What advice would you give someone just getting into Python? What did you learn over time through hard work and a few tears that would have really helped you? It's a fun game to play and we have Jason McDonald on the podcast to give us his take. Enjoy!

Watch this episode on YouTube
Play on YouTube
Watch the live stream version

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

  1. 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.
  2. 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.
  3. 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.
  4. 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 like pipenv 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 integrating venv 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.
    • Relevant Links & Tools:
      • Python Docs on venv
      • pip package manager
  5. 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.
  6. 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.
  7. Async and Await Made Approachable Despite perceptions that async programming is too advanced, Jason and Michael emphasize that async and await 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.
  8. 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.
  9. 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.
  10. 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.

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:

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

Jason C. McDonald: @codemouse92@mastodon.online
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

Talk Python's Mastodon Michael Kennedy's Mastodon