| CARVIEW |
Select Language
HTTP/2 200
date: Tue, 30 Dec 2025 22:29:01 GMT
content-type: application/xml; charset=utf-8
content-length: 39292
cache-control: public, max-age=900
content-encoding: gzip
cross-origin-opener-policy: same-origin
nel: {"report_to":"heroku-nel","response_headers":["Via"],"max_age":3600,"success_fraction":0.01,"failure_fraction":0.1}
referrer-policy: strict-origin-when-cross-origin
report-to: {"group":"heroku-nel","endpoints":[{"url":"https://nel.heroku.com/reports?s=GyH%2F1bon2A0avVojbp%2FhtDvp%2BeVFykVZVd7Aa27ZtbA%3D\u0026sid=67ff5de4-ad2b-4112-9289-cf96be89efed\u0026ts=1767133740"}],"max_age":3600}
reporting-endpoints: heroku-nel="https://nel.heroku.com/reports?s=GyH%2F1bon2A0avVojbp%2FhtDvp%2BeVFykVZVd7Aa27ZtbA%3D&sid=67ff5de4-ad2b-4112-9289-cf96be89efed&ts=1767133740"
server: cloudflare
set-cookie: cid=ab697524a9a04daa889a601990269400; expires=Wed, 30 Dec 2026 22:29:00 GMT; Max-Age=31536000; Path=/
strict-transport-security: max-age=31536000; includeSubDomains; preload
vary: Cookie, Accept-Encoding
via: 2.0 heroku-router
x-content-type-options: nosniff
x-frame-options: SAMEORIGIN
accept-ranges: bytes
cf-cache-status: BYPASS
cf-ray: 9b64f93408b9c167-BLR
alt-svc: h3=":443"; ma=86400
Real Python
2025-12-24T14:00:00+00:00
https://realpython.com/
Real Python
LlamaIndex in Python: A RAG Guide With Examples
https://realpython.com/llamaindex-examples/
2025-12-24T14:00:00+00:00
Learn how to set up LlamaIndex, choose an LLM, load your data, build and persist an index, and run queries to get grounded, reliable answers with examples.
<div><p>Discover how to use LlamaIndex with practical examples. This framework helps you build retrieval-augmented generation (RAG) apps using Python. LlamaIndex lets you load your data and documents, create and persist searchable indexes, and query an LLM using your data as context.</p>
<p>In this tutorial, you’ll learn the basics of installing the package, setting AI providers, spinning up a query engine, and running synchronous or asynchronous queries against remote or local models.</p>
<p><strong>By the end of this tutorial, you’ll understand that:</strong></p>
<ul>
<li>You use <strong>LlamaIndex</strong> to <strong>connect your data to LLMs</strong>, allowing you to <strong>build AI agents</strong>, <strong>workflows</strong>, <strong>query engines</strong>, and <strong>chat engines</strong>.</li>
<li>You can perform <strong>RAG</strong> with LlamaIndex to retrieve relevant context at query time, helping the LLM generate <strong>grounded answers</strong> and <strong>minimize hallucinations</strong>. </li>
</ul>
<p>You’ll start by preparing your environment and installing LlamaIndex. From there, you’ll learn how to load your own files, build and save an index, choose different AI providers, and run targeted queries over your data through a query engine.</p>
<div class="alert alert-warning" role="alert">
<p><strong markdown>Get Your Code:</strong> <a href="https://realpython.com/bonus/python-llamaindex-examples-code/" class="alert-link" data-toggle="modal" data-target="#modal-python-llamaindex-examples-code" markdown>Click here to download the free sample code</a> that shows you how to use LlamaIndex in Python.</p>
</div>
<div class="container border rounded text-wrap-pretty my-3">
<p class="my-3"><mark class="marker-highlight"><strong><span class="icon baseline" aria-hidden="true"><svg aria-hidden="true"><use href="/static/icons.5eccc70ec931.svg#@quiz"></use></svg></span> Take the Quiz:</strong></mark> Test your knowledge with our interactive “LlamaIndex in Python: A RAG Guide With Examples” quiz. You’ll receive a score upon completion to help you track your learning progress:</p>
<hr>
<div class="row my-3">
<div class="col-xs-12 col-sm-4 col-md-3 align-self-center">
<a href="/quizzes/llamaindex-examples/" tabindex="-1">
<div class="embed-responsive embed-responsive-16by9">
<img class="card-img-top m-0 p-0 embed-responsive-item rounded" style="object-fit: contain; background: #e5c6aa;" alt="Python LlamaIndex: Step by Step RAG With Examples" src="https://files.realpython.com/media/LlamaIndex-Example_Watermarked.de4698fa8a9b.jpg" width="1920" height="1080" srcset="/cdn-cgi/image/width=480,format=auto/https://files.realpython.com/media/LlamaIndex-Example_Watermarked.de4698fa8a9b.jpg 480w, /cdn-cgi/image/width=640,format=auto/https://files.realpython.com/media/LlamaIndex-Example_Watermarked.de4698fa8a9b.jpg 640w, /cdn-cgi/image/width=960,format=auto/https://files.realpython.com/media/LlamaIndex-Example_Watermarked.de4698fa8a9b.jpg 960w, /cdn-cgi/image/width=1920,format=auto/https://files.realpython.com/media/LlamaIndex-Example_Watermarked.de4698fa8a9b.jpg 1920w" sizes="(min-width: 1200px) 142px, (min-width: 1000px) 122px, (min-width: 780px) 112px, (min-width: 580px) 139px, calc(100vw - 62px)">
<div class="card-img-overlay d-flex align-items-center">
<div class="mx-auto">
<span class="text-light" style="opacity: 0.90;"><span class="icon baseline scale2x" aria-hidden="true"><svg aria-hidden="true"><use href="/static/icons.5eccc70ec931.svg#@quiz"></use></svg></span></span>
</div>
</div>
</div>
</a>
</div>
<div class="col">
<div class="mt-3 d-md-none"></div>
<p class="small text-muted mb-0"><strong>Interactive Quiz</strong></p>
<a href="/quizzes/llamaindex-examples/" class="stretched-link"><span class="my-0 h4">LlamaIndex in Python: A RAG Guide With Examples</span></a>
<p class="text-muted mb-0 small">Take this Python LlamaIndex quiz to test your understanding of index persistence, reloading, and performance gains in RAG applications.</p>
</div>
</div>
</div>
<h2 id="start-using-llamaindex">Start Using LlamaIndex<a class="headerlink" href="#start-using-llamaindex" title="Permanent link"></a></h2>
<p><a href="/ref/ai-coding-glossary/training/" class="ref-link">Training</a> or fine-tuning an <a href="/ref/ai-coding-glossary/ai/" class="ref-link">AI</a> model—like a <a href="/ref/ai-coding-glossary/llm/" class="ref-link">large language model (LLM)</a>—on your own data can be a complex and resource-intensive process. Instead of modifying the model itself, you can rely on a pattern called <a href="/ref/ai-coding-glossary/retrieval-augmented-generation/" class="ref-link"><strong>retrieval-augmented generation (RAG)</strong></a>.</p>
<p>RAG is a technique where the system, at query time, first retrieves relevant external documents or data and then passes them to the LLM as additional context. The model uses this context as a source of truth when generating its answer, which typically makes the response more accurate, up to date, and on topic.</p>
<div class="alert alert-primary" role="alert">
<p><strong>Note:</strong> RAG can help reduce hallucinations and prevent models from giving wrong answers. However, recent LLMs are much better at admitting when they don’t know something rather than making up an answer.</p>
</div>
<p>This technique also allows LLMs to provide answers to questions that they wouldn’t have been able to answer otherwise—for example, questions about your internal company information, email history, and similar private data.</p>
<p><a href="https://developers.llamaindex.ai/python/framework/">LlamaIndex</a> is a Python framework that enables you to build AI-powered apps capable of performing RAG. It helps you feed LLMs with your own data through indexing and retrieval tools. Next, you’ll learn the basics of installing, setting up, and using LlamaIndex in your Python projects.</p>
<h3 id="install-and-set-up-llamaindex">Install and Set Up LlamaIndex<a class="headerlink" href="#install-and-set-up-llamaindex" title="Permanent link"></a></h3>
<p>Before installing <a href="/ref/ai-coding-tools/llamaindex/" class="ref-link">LlamaIndex</a>, you should create and activate a Python <a href="/ref/glossary/virtual-environment/" class="ref-link">virtual environment</a>. Refer to <a href="https://realpython.com/python-virtual-environments-a-primer/">Python Virtual Environments: A Primer</a> for detailed instructions on how to do this.</p>
<p>Once you have the virtual environment ready, you can install LlamaIndex from the <a href="/ref/glossary/pypi/" class="ref-link">Python Package Index (PyPI)</a>:</p>
<code-block class="mb-3" aria-label="Code block" data-syntax-language="console" data-is-repl="true">
<div class="codeblock__header codeblock--yellow">
<span class="mr-2 noselect" aria-label="Language">Shell</span>
<div class="noselect">
<span class="codeblock__output-toggle" title="Toggle prompts and output" role="button"><span class="icon baseline js-codeblock-output-on codeblock__header--icon-lower" aria-hidden="true"><svg aria-hidden="true"><use href="/static/icons.5eccc70ec931.svg#regular--rectangle-terminal"></use></svg></span></span>
</div>
</div>
<div class="codeblock__contents">
<div class="highlight highlight--with-header"><pre><span></span><code><span class="gp gp-VirtualEnv">(.venv)</span> <span class="gp">$ </span>python<span class="w"> </span>-m<span class="w"> </span>pip<span class="w"> </span>install<span class="w"> </span>llama-index
</code></pre></div>
<button class="codeblock__copy btn btn-outline-secondary border m-1 px-1 d-hover-only" title="Copy to clipboard"><span class="icon baseline" aria-hidden="true"><svg aria-hidden="true"><use href="/static/icons.5eccc70ec931.svg#@copy"></use></svg></span></button>
</div>
</code-block>
<p>This command downloads the framework from PyPI and installs it in your current Python environment. In practice, <a href="https://pypi.org/project/llama-index/"><code>llama-index</code></a> is a <a href="https://developers.llamaindex.ai/python/framework/getting_started/installation/#quickstart-installation-from-pip">core starter bundle</a> of packages containing the following:</p>
<ul>
<li><code>llama-index-core</code></li>
<li><code>llama-index-llms-openai</code></li>
<li><code>llama-index-embeddings-openai</code></li>
<li><code>llama-index-readers-file</code></li>
</ul>
<p>As you can see, OpenAI is the default LLM provider for LlamaIndex. In this tutorial, you’ll rely on this default setting, so after installation, you must set up an environment variable called <code>OPENAI_API_KEY</code> that points to a valid OpenAI <a href="https://platform.openai.com/api-keys">API key</a>:</p>
<ul class="nav nav-tabs justify-content-end js-platform-widget-tabs" role="tablist">
<li class="nav-item mb-0 js-platform-widget-tab-windows" role="presentation">
<a class="nav-link link-unstyled text-body active small" id="windows-tab-1" data-toggle="tab" href="#windows-1" role="tab" aria-controls="windows-1" aria-selected="true"><span class="icon baseline text-muted mr-1" aria-hidden="true"><svg aria-hidden="true"><use href="/static/icons.5eccc70ec931.svg#brands--windows"></use></svg></span>Windows</a>
</li>
<li class="nav-item mb-0 js-platform-widget-tab-linuxmacos" role="presentation">
<a class="nav-link link-unstyled text-body small" id="macos-tab-1" data-toggle="tab" href="#linux-macos-1" role="tab" aria-controls="linux-macos-1" aria-selected="false"><span class="icon baseline text-muted" aria-hidden="true"><svg aria-hidden="true"><use href="/static/icons.5eccc70ec931.svg#v4--linux"></use></svg></span><span class="icon baseline text-muted mr-1" aria-hidden="true"><svg aria-hidden="true"><use href="/static/icons.5eccc70ec931.svg#v4--apple"></use></svg></span>Linux + macOS</a>
</li>
</ul>
<div class="tab-content mt-2 mb-0 js-platform-widget-content">
<div aria-labelledby="windows-tab-1" class="tab-pane fade show active" id="windows-1" role="tabpanel">
<code-block class="mb-3" aria-label="Code block" data-syntax-language="pscon" data-is-repl="true">
<div class="codeblock__header codeblock--yellow">
<span class="mr-2 noselect" aria-label="Language">Windows PowerShell</span>
<div class="noselect">
<span class="codeblock__output-toggle" title="Toggle prompts and output" role="button"><span class="icon baseline js-codeblock-output-on codeblock__header--icon-lower" aria-hidden="true"><svg aria-hidden="true"><use href="/static/icons.5eccc70ec931.svg#regular--rectangle-terminal"></use></svg></span></span>
</div>
</div>
<div class="codeblock__contents">
<div class="highlight highlight--with-header"><pre><span></span><code><span class="gp gp-VirtualEnv">(.venv)</span> <span class="gp">PS> </span><span class="nv">$ENV:OPENAI_API_KEY</span> <span class="p">=</span> <span class="s2">"<your-api-key-here>"</span>
</code></pre></div>
<button class="codeblock__copy btn btn-outline-secondary border m-1 px-1 d-hover-only" title="Copy to clipboard"><span class="icon baseline" aria-hidden="true"><svg aria-hidden="true"><use href="/static/icons.5eccc70ec931.svg#@copy"></use></svg></span></button>
</div>
</code-block>
</div>
<div aria-labelledby="linux-macos-tab-1" class="tab-pane fade " id="linux-macos-1" role="tabpanel">
<code-block class="mb-3" aria-label="Code block" data-syntax-language="console" data-is-repl="true">
<div class="codeblock__header codeblock--yellow">
<span class="mr-2 noselect" aria-label="Language">Shell</span>
<div class="noselect">
<span class="codeblock__output-toggle" title="Toggle prompts and output" role="button"><span class="icon baseline js-codeblock-output-on codeblock__header--icon-lower" aria-hidden="true"><svg aria-hidden="true"><use href="/static/icons.5eccc70ec931.svg#regular--rectangle-terminal"></use></svg></span></span>
</div>
</div>
<div class="codeblock__contents">
<div class="highlight highlight--with-header"><pre><span></span><code><span class="gp gp-VirtualEnv">(.venv)</span> <span class="gp">$ </span><span class="nb">export</span><span class="w"> </span><span class="nv">OPENAI_API_KEY</span><span class="o">=</span><span class="s2">"<your-api-key-here>"</span>
</code></pre></div>
<button class="codeblock__copy btn btn-outline-secondary border m-1 px-1 d-hover-only" title="Copy to clipboard"><span class="icon baseline" aria-hidden="true"><svg aria-hidden="true"><use href="/static/icons.5eccc70ec931.svg#@copy"></use></svg></span></button>
</div>
</code-block>
</div>
</div>
<p>With this command, you make the API key accessible under the environment variable <code>OPENAI_API_KEY</code> in your current <a href="https://realpython.com/terminal-commands/">terminal</a> session. Note that you’ll lose it when you close your terminal. To persist this variable, add the <code>export</code> command to your shell’s configuration file—typically <code>~/.bashrc</code> or <code>~/.zshrc</code> on Linux and macOS—or use the <em>System Properties</em> dialog on Windows.</p>
<p>LlamaIndex also supports many other LLMs. For a complete list of models, visit the <a href="https://developers.llamaindex.ai/python/framework/module_guides/models/llms/modules">Available LLM integrations</a> section in the official <a href="https://developers.llamaindex.ai/python/framework/">documentation</a>.</p>
<h3 id="run-a-quick-llamaindex-rag-example">Run a Quick LlamaIndex RAG Example<a class="headerlink" href="#run-a-quick-llamaindex-rag-example" title="Permanent link"></a></h3>
</div><h2><a href="https://realpython.com/llamaindex-examples/?utm_source=realpython&utm_medium=rss">Read the full article at https://realpython.com/llamaindex-examples/ »</a></h2>
<hr />
<p><em>[ Improve Your Python With 🐍 Python Tricks 💌 – Get a short & sweet Python Trick delivered to your inbox every couple of days. <a href="https://realpython.com/python-tricks/?utm_source=realpython&utm_medium=rss&utm_campaign=footer">>> Click here to learn more and see examples</a> ]</em></p>
Quiz: LlamaIndex in Python: A RAG Guide With Examples
https://realpython.com/quizzes/llamaindex-examples/
2025-12-24T12:00:00+00:00
Take this Python LlamaIndex quiz to test your understanding of index persistence, reloading, and performance gains in RAG applications.
<p>In this quiz, you’ll test your understanding of the <a href="https://realpython.com/llamaindex-examples/">LlamaIndex in Python: A RAG Guide With Examples</a> tutorial.</p>
<p>By working through this quiz, you’ll revisit how to create and persist an index to disk, review how to reload it, and see why persistence improves performance, lowers costs, saves time, and keeps results consistent.</p>
<hr />
<p><em>[ Improve Your Python With 🐍 Python Tricks 💌 – Get a short & sweet Python Trick delivered to your inbox every couple of days. <a href="https://realpython.com/python-tricks/?utm_source=realpython&utm_medium=rss&utm_campaign=footer">>> Click here to learn more and see examples</a> ]</em></p>
Reading User Input From the Keyboard With Python
https://realpython.com/courses/reading-user-input-from-keyboard/
2025-12-23T14:00:00+00:00
Master taking user input in Python to build interactive terminal apps with clear prompts, solid error handling, and smooth multi-step flows.
<p>You may often want to make your Python programs more interactive by responding dynamically to input from the user. Learning how to read user input from the keyboard unlocks exciting possibilities and can make your code far more useful.</p>
<p>The ability to gather input from the keyboard with Python allows you to build programs that can respond uniquely based on the preferences, decisions, or data provided by different users. By fetching input and assigning it to variables, your code can react to adjustable conditions rather than just executing static logic flows. This personalizes programs to individual users.</p>
<p>The <code>input()</code> function is the simplest way to get keyboard data from the user in Python. When called, it asks the user for input with a prompt that you specify, and it waits for the user to type a response and press the <span class="keys"><kbd class="key-enter">Enter</kbd></span> key before continuing. This response string is returned by <code>input()</code> so you can save it to a variable or use it directly.</p>
<p>Using only Python, you can start building interactive programs that accept customizable data from the user right within the terminal. Taking user input is an essential skill that unlocks more dynamic Python coding and allows you to elevate simple scripts into personalized applications.</p>
<hr />
<p><em>[ Improve Your Python With 🐍 Python Tricks 💌 – Get a short & sweet Python Trick delivered to your inbox every couple of days. <a href="https://realpython.com/python-tricks/?utm_source=realpython&utm_medium=rss&utm_campaign=footer">>> Click here to learn more and see examples</a> ]</em></p>
Quiz: Recursion in Python: An Introduction
https://realpython.com/quizzes/python-recursion/
2025-12-23T12:00:00+00:00
Test your understanding of recursion in Python, including base cases, recursive structure, performance considerations, and common use cases.
<p>In this quiz, you’ll test your understanding of
<a href="https://realpython.com/python-recursion/">Recursion in Python</a>.</p>
<p>By working through this quiz, you’ll revisit what recursion is, how base and recursive cases work, when recursion is a good fit for a problem, and when an iterative approach fits.</p>
<hr />
<p><em>[ Improve Your Python With 🐍 Python Tricks 💌 – Get a short & sweet Python Trick delivered to your inbox every couple of days. <a href="https://realpython.com/python-tricks/?utm_source=realpython&utm_medium=rss&utm_campaign=footer">>> Click here to learn more and see examples</a> ]</em></p>
SOLID Design Principles: Improve Object-Oriented Code in Python
https://realpython.com/solid-principles-python/
2025-12-22T14:00:00+00:00
Learn how to apply SOLID design principles in Python and build maintainable, reusable, and testable object-oriented code.
<div><p>A great approach to writing high-quality object-oriented Python code is to consistently apply the SOLID design principles. SOLID is a set of five object-oriented design principles that can help you write maintainable, flexible, and scalable code based on well-designed, cleanly structured classes. These principles are foundational best practices in object-oriented design.</p>
<p>In this tutorial, you’ll explore each of these principles with concrete examples and refactor your code so that it adheres to the principle at hand.</p>
<p><strong>By the end of this tutorial, you’ll understand that:</strong></p>
<ul>
<li>You apply the <strong>SOLID</strong> design principles to write classes that you can confidently maintain, extend, test, and reason about.</li>
<li>You can apply SOLID principles to split <strong>responsibilities</strong>, extend via <strong>abstractions</strong>, honor <strong>subtype contracts</strong>, keep <strong>interfaces</strong> small, and <strong>invert dependencies</strong>.</li>
<li>You enforce the <strong>Single-Responsibility Principle</strong> by separating tasks into specialized classes, giving each class only <strong>one reason to change</strong>.</li>
<li>You satisfy the <strong>Open-Closed Principle</strong> by defining an abstract class with the required interface and adding new <strong>subclasses</strong> without modifying existing code.</li>
<li>You honor the <strong>Liskov Substitution Principle</strong> by making the subtypes preserve their <strong>expected behaviors</strong>.</li>
<li>You implement <strong>Dependency Inversion</strong> by making your classes depend on <strong>abstractions</strong> rather than on details.</li>
</ul>
<p>Follow the examples to refactor each design, verify behaviors, and internalize how each SOLID design principle can improve your code.</p>
<div class="alert alert-warning" role="alert">
<p><strong markdown>Free Bonus:</strong> <a href="https://realpython.com/bonus/solid-principles-python-code/" class="alert-link" data-toggle="modal" data-target="#modal-solid-principles-python-code" markdown>Click here to download sample code</a> so you can build clean, maintainable classes with the SOLID Principles in Python.</p>
</div>
<div class="container border rounded text-wrap-pretty my-3">
<p class="my-3"><mark class="marker-highlight"><strong><span class="icon baseline" aria-hidden="true"><svg aria-hidden="true"><use href="/static/icons.5eccc70ec931.svg#@quiz"></use></svg></span> Take the Quiz:</strong></mark> Test your knowledge with our interactive “SOLID Design Principles: Improve Object-Oriented Code in Python” quiz. You’ll receive a score upon completion to help you track your learning progress:</p>
<hr>
<div class="row my-3">
<div class="col-xs-12 col-sm-4 col-md-3 align-self-center">
<a href="/quizzes/solid-principles-python/" tabindex="-1">
<div class="embed-responsive embed-responsive-16by9">
<img class="card-img-top m-0 p-0 embed-responsive-item rounded" style="object-fit: contain; background: #ffc873;" alt="SOLID Principles: Improve Object-Oriented Design in Python" src="https://files.realpython.com/media/The-SOLID-Principles-in-Python-Improve-Your-OOP-Design_Watermarked.a70bbae152e8.jpg" width="1920" height="1080" srcset="/cdn-cgi/image/width=480,format=auto/https://files.realpython.com/media/The-SOLID-Principles-in-Python-Improve-Your-OOP-Design_Watermarked.a70bbae152e8.jpg 480w, /cdn-cgi/image/width=640,format=auto/https://files.realpython.com/media/The-SOLID-Principles-in-Python-Improve-Your-OOP-Design_Watermarked.a70bbae152e8.jpg 640w, /cdn-cgi/image/width=960,format=auto/https://files.realpython.com/media/The-SOLID-Principles-in-Python-Improve-Your-OOP-Design_Watermarked.a70bbae152e8.jpg 960w, /cdn-cgi/image/width=1920,format=auto/https://files.realpython.com/media/The-SOLID-Principles-in-Python-Improve-Your-OOP-Design_Watermarked.a70bbae152e8.jpg 1920w" sizes="(min-width: 1200px) 142px, (min-width: 1000px) 122px, (min-width: 780px) 112px, (min-width: 580px) 139px, calc(100vw - 62px)">
<div class="card-img-overlay d-flex align-items-center">
<div class="mx-auto">
<span class="text-light" style="opacity: 0.90;"><span class="icon baseline scale2x" aria-hidden="true"><svg aria-hidden="true"><use href="/static/icons.5eccc70ec931.svg#@quiz"></use></svg></span></span>
</div>
</div>
</div>
</a>
</div>
<div class="col">
<div class="mt-3 d-md-none"></div>
<p class="small text-muted mb-0"><strong>Interactive Quiz</strong></p>
<a href="/quizzes/solid-principles-python/" class="stretched-link"><span class="my-0 h4">SOLID Design Principles: Improve Object-Oriented Code in Python</span></a>
<p class="text-muted mb-0 small">Learn Liskov substitution in Python. Spot Square and Rectangle pitfalls and design safer APIs with polymorphism. Test your understanding now.</p>
</div>
</div>
</div>
<h2 id="the-solid-design-principles-in-python">The SOLID Design Principles in Python<a class="headerlink" href="#the-solid-design-principles-in-python" title="Permanent link"></a></h2>
<p>When it comes to writing <a href="https://realpython.com/python-classes/">classes</a> and designing their interactions in Python, you can follow a series of principles that will help you build better object-oriented code. One of the most popular and widely accepted sets of standards for <a href="https://en.wikipedia.org/wiki/Object-oriented_design">object-oriented design (OOD)</a> is known as the <a href="https://en.wikipedia.org/wiki/SOLID">SOLID</a> design principles.</p>
<p>If you’re coming from <a href="https://realpython.com/python-vs-cpp/">C++</a> or <a href="https://realpython.com/oop-in-python-vs-java/">Java</a>, you may already be familiar with these principles. Maybe you’re wondering if the SOLID principles also apply to Python code. The answer to that question is a resounding <em>yes</em>. If you’re writing object-oriented code, then you should consider applying these principles to your OOD.</p>
<p>But what are these SOLID design principles? SOLID is an acronym that encompasses five core principles applicable to object-oriented design. These principles are the following:</p>
<ol>
<li><a href="https://en.wikipedia.org/wiki/Single-responsibility_principle"><strong>S</strong>ingle-responsibility principle (SRP)</a></li>
<li><a href="https://en.wikipedia.org/wiki/Open%E2%80%93closed_principle"><strong>O</strong>pen–closed principle (OCP)</a></li>
<li><a href="https://en.wikipedia.org/wiki/Liskov_substitution_principle"><strong>L</strong>iskov substitution principle (LSP)</a></li>
<li><a href="https://en.wikipedia.org/wiki/Interface_segregation_principle"><strong>I</strong>nterface segregation principle (ISP)</a></li>
<li><a href="https://en.wikipedia.org/wiki/Dependency_inversion_principle"><strong>D</strong>ependency inversion principle (DIP)</a></li>
</ol>
<p>You’ll explore each of these principles in detail and code real-world examples of how to apply them in Python. In the process, you’ll gain a strong understanding of how to write more straightforward, organized, scalable, and reusable object-oriented code by applying the SOLID design principles. To kick things off, you’ll start with the first principle on the list.</p>
<h2 id="single-responsibility-principle-srp">Single-Responsibility Principle (SRP)<a class="headerlink" href="#single-responsibility-principle-srp" title="Permanent link"></a></h2>
<p>The <strong>single-responsibility principle (SRP)</strong> comes from <a href="https://en.wikipedia.org/wiki/Robert_C._Martin">Robert C. Martin</a>, more commonly known by his nickname Uncle Bob. Martin is a well-respected figure in software engineering and one of the original signatories of the <a href="https://en.wikipedia.org/wiki/Agile_software_development#The_Agile_Manifesto">Agile Manifesto</a>. He coined the term <strong>SOLID</strong>.</p>
<p>The single-responsibility principle states that:</p>
<blockquote>
<p>A class should have only one reason to change.</p>
</blockquote>
<p>This means that a class should have only one <strong>responsibility</strong>, as expressed through its <a href="/ref/glossary/method/" class="ref-link">methods</a>. If a class takes care of more than one task, then you should separate those tasks into dedicated classes with descriptive names. Note that SRP isn’t only about <em>responsibility</em> but also about the <em>reasons for changing</em> the class implementation.</p>
<div class="alert alert-primary" role="alert">
<p><strong>Note:</strong> You’ll find the SOLID design principles worded in various ways out there. In this tutorial, you’ll refer to them following the wording that Uncle Bob uses in his book <a href="https://realpython.com/asins/0131857258/">Agile Software Development: Principles, Patterns, and Practices</a>. So, all the direct quotes come from this book.</p>
<p>If you want to read alternate wordings in a quick roundup of these and related principles, then check out Uncle Bob’s <a href="https://butunclebob.com/ArticleS.UncleBob.PrinciplesOfOod">The Principles of OOD</a>.</p>
</div>
<p>This principle is closely related to the concept of <a href="https://en.wikipedia.org/wiki/Separation_of_concerns">separation of concerns</a>, which suggests that you should divide your programs into components, each addressing a separate concern.</p>
<p>To illustrate the single-responsibility principle and how it can help you improve your object-oriented design, say that you have the following <code>FileManager</code> class:</p>
<code-block class="mb-3" aria-label="Code block" data-syntax-language="python">
<div class="codeblock__header codeblock--blue">
<span class="mr-2 noselect" aria-label="Language">Python</span>
<span class="mr-2" aria-label="Filename"><code style="color: inherit; background: inherit;">file_manager_srp.py</code></span>
<div class="noselect">
</div>
</div>
<div class="codeblock__contents">
<div class="highlight highlight--with-header"><pre><span></span><code><span class="kn">from</span><span class="w"> </span><span class="nn">pathlib</span><span class="w"> </span><span class="kn">import</span> <span class="n">Path</span>
<span class="kn">from</span><span class="w"> </span><span class="nn">zipfile</span><span class="w"> </span><span class="kn">import</span> <span class="n">ZipFile</span>
<span class="k">class</span><span class="w"> </span><span class="nc">FileManager</span><span class="p">:</span>
<span class="k">def</span><span class="w"> </span><span class="fm">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">filename</span><span class="p">):</span>
<span class="bp">self</span><span class="o">.</span><span class="n">path</span> <span class="o">=</span> <span class="n">Path</span><span class="p">(</span><span class="n">filename</span><span class="p">)</span>
<span class="k">def</span><span class="w"> </span><span class="nf">read</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">encoding</span><span class="o">=</span><span class="s2">"utf-8"</span><span class="p">):</span>
<span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">path</span><span class="o">.</span><span class="n">read_text</span><span class="p">(</span><span class="n">encoding</span><span class="p">)</span>
<span class="k">def</span><span class="w"> </span><span class="nf">write</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">data</span><span class="p">,</span> <span class="n">encoding</span><span class="o">=</span><span class="s2">"utf-8"</span><span class="p">):</span>
<span class="bp">self</span><span class="o">.</span><span class="n">path</span><span class="o">.</span><span class="n">write_text</span><span class="p">(</span><span class="n">data</span><span class="p">,</span> <span class="n">encoding</span><span class="p">)</span>
<span class="k">def</span><span class="w"> </span><span class="nf">compress</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<span class="k">with</span> <span class="n">ZipFile</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">path</span><span class="o">.</span><span class="n">with_suffix</span><span class="p">(</span><span class="s2">".zip"</span><span class="p">),</span> <span class="n">mode</span><span class="o">=</span><span class="s2">"w"</span><span class="p">)</span> <span class="k">as</span> <span class="n">archive</span><span class="p">:</span>
<span class="n">archive</span><span class="o">.</span><span class="n">write</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">path</span><span class="p">)</span>
<span class="k">def</span><span class="w"> </span><span class="nf">decompress</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<span class="k">with</span> <span class="n">ZipFile</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">path</span><span class="o">.</span><span class="n">with_suffix</span><span class="p">(</span><span class="s2">".zip"</span><span class="p">),</span> <span class="n">mode</span><span class="o">=</span><span class="s2">"r"</span><span class="p">)</span> <span class="k">as</span> <span class="n">archive</span><span class="p">:</span>
<span class="n">archive</span><span class="o">.</span><span class="n">extractall</span><span class="p">()</span>
</code></pre></div>
<button class="codeblock__copy btn btn-outline-secondary border m-1 px-1 d-hover-only" title="Copy to clipboard"><span class="icon baseline" aria-hidden="true"><svg aria-hidden="true"><use href="/static/icons.5eccc70ec931.svg#@copy"></use></svg></span></button>
</div>
</code-block>
<p>In this example, your <code>FileManager</code> class has two different responsibilities. It manages files using the <code>.read()</code> and <code>.write()</code> methods. It also deals with <a href="https://realpython.com/python-zipfile/">ZIP archives</a> by providing the <code>.compress()</code> and <code>.decompress()</code> methods.</p>
<p>This class violates the single-responsibility principle because there is more than one reason for changing its implementation (file <a href="/ref/glossary/input-output/" class="ref-link">I/O</a> and ZIP handling). This implementation also makes code testing and code reuse harder.</p>
<p>To fix this issue and make your design more robust, you can split the class into two smaller, more focused classes, each with its own specific concern:</p>
</div><h2><a href="https://realpython.com/solid-principles-python/?utm_source=realpython&utm_medium=rss">Read the full article at https://realpython.com/solid-principles-python/ »</a></h2>
<hr />
<p><em>[ Improve Your Python With 🐍 Python Tricks 💌 – Get a short & sweet Python Trick delivered to your inbox every couple of days. <a href="https://realpython.com/python-tricks/?utm_source=realpython&utm_medium=rss&utm_campaign=footer">>> Click here to learn more and see examples</a> ]</em></p>
Quiz: SOLID Design Principles: Improve Object-Oriented Code in Python
https://realpython.com/quizzes/solid-principles-python/
2025-12-22T12:00:00+00:00
Learn Liskov substitution in Python. Spot Square and Rectangle pitfalls and design safer APIs with polymorphism. Test your understanding now.
<p>In this quiz, you’ll test your understanding of the <a href="https://realpython.com/solid-principles-python/">SOLID Design Principles: Improve Object-Oriented Code in Python</a> tutorial.</p>
<p>You will reason about behavior contracts, attribute invariants, and choosing composition or separate types over inheritance. For a refresher, you can watch the <a href="https://realpython.com/courses/solid-principles-python/">Design and Guidance: Object-Oriented Programming in Python</a> course.</p>
<hr />
<p><em>[ Improve Your Python With 🐍 Python Tricks 💌 – Get a short & sweet Python Trick delivered to your inbox every couple of days. <a href="https://realpython.com/python-tricks/?utm_source=realpython&utm_medium=rss&utm_campaign=footer">>> Click here to learn more and see examples</a> ]</em></p>
The Real Python Podcast – Episode #277: Moving Towards Spec-Driven Development
https://realpython.com/podcasts/rpp/277/
2025-12-19T12:00:00+00:00
What are the advantages of spec-driven development compared to vibe coding with an LLM? Are these recent trends a move toward declarative programming? This week on the show, Marc Brooker, VP and Distinguished Engineer at AWS, joins us to discuss specification-driven development and Kiro.
<p>What are the advantages of spec-driven development compared to vibe coding with an LLM? Are these recent trends a move toward declarative programming? This week on the show, Marc Brooker, VP and Distinguished Engineer at AWS, joins us to discuss specification-driven development and Kiro.</p>
<hr />
<p><em>[ Improve Your Python With 🐍 Python Tricks 💌 – Get a short & sweet Python Trick delivered to your inbox every couple of days. <a href="https://realpython.com/python-tricks/?utm_source=realpython&utm_medium=rss&utm_campaign=footer">>> Click here to learn more and see examples</a> ]</em></p>
How to Build the Python Skills That Get You Hired
https://realpython.com/python-skills/
2025-12-17T14:00:00+00:00
Build a focused learning plan that helps you identify essential Python skills, assess your strengths, and practice effectively to progress.
<div><p>When you’re learning Python, the sheer volume of topics to explore can feel overwhelming because there’s <em>so much</em> you could focus on. Should you dive into web frameworks before exploring data science? Is test-driven development something you need right away? And which skills actually matter to employers in the age of AI-assisted software development?</p>
<p><strong>By the end of this tutorial, you’ll have:</strong></p>
<ul>
<li>A clear understanding of which <strong>Python skills</strong> employers consistently look for</li>
<li>A personalized <strong>Python developer roadmap</strong> showing where you are and where you need to go</li>
<li>A <strong>weekly practice plan</strong> that makes consistent progress feel achievable</li>
</ul>
<p>Python itself is relatively beginner-friendly, but its versatility makes it easy to wander without direction. Without a clear plan, you can spend months studying topics that won’t help you land your first developer job.</p>
<p>This guide will show you how to build a focused learning strategy that aligns with real job market demands. You’ll learn how to research what employers value, assess your current strengths and gaps, and structure a practice routine that turns scattered study sessions into steady progress.</p>
<p>Instead of guessing what to learn next, you’ll have a concrete document that shows you exactly where to focus:</p>
<figure class="js-lightbox"><a href="https://files.realpython.com/media/python-skills-worksheet-link.4e0ad67920ee.png" target="_blank"><img loading="lazy" class="img-fluid mx-auto d-block border " src="https://files.realpython.com/media/python-skills-worksheet-link.4e0ad67920ee.png" width="1920" height="1080" srcset="/cdn-cgi/image/width=480,format=auto/https://files.realpython.com/media/python-skills-worksheet-link.4e0ad67920ee.png 480w, /cdn-cgi/image/width=640,format=auto/https://files.realpython.com/media/python-skills-worksheet-link.4e0ad67920ee.png 640w, /cdn-cgi/image/width=960,format=auto/https://files.realpython.com/media/python-skills-worksheet-link.4e0ad67920ee.png 960w, /cdn-cgi/image/width=1920,format=auto/https://files.realpython.com/media/python-skills-worksheet-link.4e0ad67920ee.png 1920w" sizes="(min-width: 1200px) 690px, (min-width: 780px) calc(-5vw + 669px), (min-width: 580px) 510px, calc(100vw - 30px)" alt="The Python skills worksheet as a table with one row filled out and a link showing on hover" data-asset="6692"></a></figure>
<p>Work through this tutorial to identify the skills you need and set yourself up for success.</p>
<div class="alert alert-warning" role="alert">
<p><strong markdown>Get Your Downloads:</strong> <a href="https://realpython.com/bonus/python-skills-materials/" class="alert-link" data-toggle="modal" data-target="#modal-python-skills-materials" markdown>Click here to download the free materials</a> that will help you build the Python skills that get you hired.</p>
</div>
<h2 id="step-1-identify-the-python-skills-employers-value-most">Step 1: Identify the Python Skills Employers Value Most<a class="headerlink" href="#step-1-identify-the-python-skills-employers-value-most" title="Permanent link"></a></h2>
<p>Before you dive into another tutorial or framework, you need to understand what the job market actually rewards. Most Python learners make the mistake of studying everything that sounds interesting. You’ll make faster progress by focusing on the skills that appear in job posting after job posting.</p>
<h3 id="research-real-job-requirements">Research Real Job Requirements<a class="headerlink" href="#research-real-job-requirements" title="Permanent link"></a></h3>
<p>Start by opening five to ten current job listings for Python-related positions. Look for titles like <em>Python Developer</em>, <em>Backend Engineer</em>, <em>Data Analyst</em>, or <em>Machine Learning Engineer</em> on sites like <a href="https://www.indeed.com/">Indeed</a>, <a href="https://stackoverflowjobs.com/">Stack Overflow Jobs</a>, and <a href="https://www.linkedin.com/jobs/">LinkedIn</a>. As you read through these postings, highlight the <strong>technical requirements</strong> that appear repeatedly. You’ll quickly start to notice patterns.</p>
<p>To illustrate, consider a few examples of different roles involving Python:</p>
<ul>
<li><a href="https://realpython.com/learning-paths/become-python-web-developer/">Web development</a> roles often emphasize frameworks like <a href="https://realpython.com/learning-paths/flask-by-example/">Flask</a>, <a href="https://realpython.com/learning-paths/django-web-development/">Django</a>, and, more recently, <a href="https://realpython.com/get-started-with-fastapi/">FastAPI</a>, along with <a href="https://realpython.com/learning-paths/database-access-in-python/">database</a> knowledge and <a href="https://realpython.com/api-integration-in-python/">REST API</a> design. Employers often seek full-stack engineers who feel comfortable working on the backend as well as <a href="https://realpython.com/tutorials/front-end/">frontend</a>, including <a href="https://realpython.com/python-vs-javascript/">JavaScript</a>, <a href="https://realpython.com/html-css-python/">HTML, and CSS</a>.</li>
<li><a href="https://realpython.com/learning-paths/data-science-python-core-skills/">Data science</a> positions highlight libraries like <a href="https://realpython.com/numpy-tutorial/">NumPy</a>, <a href="https://realpython.com/learning-paths/pandas-data-science/">pandas</a>, <a href="https://realpython.com/polars-python/">Polars</a>, and <a href="https://realpython.com/python-matplotlib-guide/">Matplotlib</a>, plus an understanding of <a href="https://realpython.com/python-statistics/">statistical concepts</a>.</li>
<li><a href="https://realpython.com/learning-paths/machine-learning-python/">Machine learning</a> jobs typically add <a href="https://realpython.com/pytorch-vs-tensorflow/">PyTorch or TensorFlow</a> to the mix.</li>
<li><a href="https://en.wikipedia.org/wiki/Test_automation">Test automation</a> roles likely require familiarity with frameworks such as <a href="https://realpython.com/modern-web-automation-with-python-and-selenium/">Selenium</a>, Playwright, or <a href="https://realpython.com/web-scraping-with-scrapy-and-mongodb/">Scrapy</a>.</li>
</ul>
<p>Despite these differences, nearly every job posting shares a <strong>common core</strong>. Employers want developers who understand <a href="https://realpython.com/learning-paths/python3-introduction/">Python fundamentals</a> deeply. They should also be able to use version control with <a href="https://realpython.com/python-git-github-intro/">Git</a>, write <a href="https://realpython.com/learning-paths/test-your-python-apps/">unit tests</a> for their code, and <a href="https://realpython.com/learning-paths/exception-handling-logging-debugging/">debug</a> problems systematically. Familiarity with <a href="https://realpython.com/learning-paths/python-devops/">DevOps</a> practices and <a href="https://realpython.com/django-hosting-on-heroku/">cloud platforms</a> is often a plus. These professional practices matter as much as knowing any specific framework.</p>
<p>Increasingly, job postings also expect familiarity with <a href="/ref/ai-coding-tools/" class="ref-link">AI coding tools</a> like <a href="/ref/ai-coding-tools/github-copilot-chat/" class="ref-link">GitHub Copilot</a>, <a href="/ref/ai-coding-tools/gemini-cli/" class="ref-link">Gemini CLI</a>, <a href="/ref/ai-coding-tools/cursor/" class="ref-link">Cursor</a>, or <a href="/ref/ai-coding-tools/claude-code/" class="ref-link">Claude Code</a>. Employers want developers who can use these tools productively while maintaining the judgment to review and validate AI-generated code.</p>
<div class="alert alert-primary" role="alert">
<p><strong>Note:</strong> With AI tools handling more routine coding tasks, employers increasingly value developers who can <em>think at the system level</em>. </p>
<p>Understanding how components fit together, how to design scalable architectures, and how to make sound trade-offs between approaches matters more than ever. These system design skills are harder to outsource to AI because they require judgment about business requirements, user needs, and long-term maintainability.</p>
</div>
<p>Your informal survey will reflect what large-scale research confirms. The <a href="https://survey.stackoverflow.co/2025/technology#most-popular-technologies">Stack Overflow Developer Survey</a> ranks Python as one of the most widely used programming languages across all professional roles. The survey also reveals that Python appears in diverse fields, including finance, healthcare, education, and scientific research.</p>
<p>This trend is echoed by the <a href="https://www.tiobe.com/tiobe-index/">TIOBE Index</a>, a monthly ranking of programming language popularity, where Python consistently appears at or near the top:</p>
<figure class="js-lightbox"><a href="https://files.realpython.com/media/Screenshot_From_2025-11-13_19-05-15.a6ccfe59dec8.png" target="_blank"><img loading="lazy" class="img-fluid mx-auto d-block border " src="https://files.realpython.com/media/Screenshot_From_2025-11-13_19-05-15.a6ccfe59dec8.png" width="1378" height="465" srcset="/cdn-cgi/image/width=344,format=auto/https://files.realpython.com/media/Screenshot_From_2025-11-13_19-05-15.a6ccfe59dec8.png 344w, /cdn-cgi/image/width=459,format=auto/https://files.realpython.com/media/Screenshot_From_2025-11-13_19-05-15.a6ccfe59dec8.png 459w, /cdn-cgi/image/width=689,format=auto/https://files.realpython.com/media/Screenshot_From_2025-11-13_19-05-15.a6ccfe59dec8.png 689w, /cdn-cgi/image/width=1378,format=auto/https://files.realpython.com/media/Screenshot_From_2025-11-13_19-05-15.a6ccfe59dec8.png 1378w" sizes="(min-width: 1200px) 690px, (min-width: 780px) calc(-5vw + 669px), (min-width: 580px) 510px, calc(100vw - 30px)" alt="TIOBE Index" data-asset="6643"></a><figcaption class="figure-caption text-center">TIOBE Index</figcaption></figure>
<p>Similarly, LinkedIn’s <a href="https://learning.linkedin.com/resources/workplace-learning-report-2023">Workplace Learning Report 2023</a> named Python as one of the most in-demand technical skills globally. Python’s versatility means that mastering its fundamentals opens doors across multiple career paths.</p>
<h3 id="understand-different-developer-paths">Understand Different Developer Paths<a class="headerlink" href="#understand-different-developer-paths" title="Permanent link"></a></h3>
<p>Python is a phenomenally versatile language. On the one hand, school teachers choose it to help their pupils learn how to program, often starting with fun, visual tools like the built-in <a href="https://realpython.com/beginners-guide-python-turtle/"><code>turtle</code> graphics</a> module. At the same time, Python runs major platforms like Instagram, plays a role in powering large services such as YouTube, and supports the development of generative AI models. It even once helped <a href="https://realpython.com/python-news-march-2021/#python-lands-on-mars">control the helicopter</a> flying on Mars!</p>
<div class="alert alert-primary" role="alert">
<p><strong>Note:</strong> Check out <a href="https://realpython.com/what-can-i-do-with-python/">What Can I Do With Python?</a> to discover how Python helps build software, power AI, automate tasks, drive robotics, and more.</p>
</div>
</div><h2><a href="https://realpython.com/python-skills/?utm_source=realpython&utm_medium=rss">Read the full article at https://realpython.com/python-skills/ »</a></h2>
<hr />
<p><em>[ Improve Your Python With 🐍 Python Tricks 💌 – Get a short & sweet Python Trick delivered to your inbox every couple of days. <a href="https://realpython.com/python-tricks/?utm_source=realpython&utm_medium=rss&utm_campaign=footer">>> Click here to learn more and see examples</a> ]</em></p>
Exploring Asynchronous Iterators and Iterables
https://realpython.com/courses/asynchronous-iterators-iterables/
2025-12-16T14:00:00+00:00
Learn to build async iterators and iterables in Python to handle async operations efficiently and write cleaner, faster code.
<p>When you write asynchronous code in Python, you’ll likely need to create asynchronous iterators and iterables at some point. Asynchronous iterators are what Python uses to control <code>async for</code> loops, while asynchronous iterables are objects that you can iterate over using <code>async for</code> loops.</p>
<p>Both tools allow you to iterate over awaitable objects without blocking your code. This way, you can perform different tasks asynchronously.</p>
<p><strong>In this video course, you’ll:</strong></p>
<ul>
<li>Learn what <strong>async iterators</strong> and <strong>iterables</strong> are in Python</li>
<li>Create async <strong>generator expressions</strong> and <strong>generator iterators</strong></li>
<li>Code async iterators and iterables with the <strong><code>.__aiter__()</code></strong> and <strong><code>.__anext__()</code></strong> methods</li>
<li>Use async iterators in <strong>async loops</strong> and <strong>comprehensions</strong></li>
</ul>
<hr />
<p><em>[ Improve Your Python With 🐍 Python Tricks 💌 – Get a short & sweet Python Trick delivered to your inbox every couple of days. <a href="https://realpython.com/python-tricks/?utm_source=realpython&utm_medium=rss&utm_campaign=footer">>> Click here to learn more and see examples</a> ]</em></p>
Writing DataFrame-Agnostic Python Code With Narwhals
https://realpython.com/narwhals-python/
2025-12-15T14:00:00+00:00
If you're a Python library developer looking to write DataFrame-agnostic code, this tutorial will show how the Narwhals library could give you a solution.
<div><p>Narwhals is intended for Python library developers who need to analyze DataFrames in a range of standard formats, including Polars, pandas, DuckDB, and others. It does this by providing a compatibility layer of code that handles any differences between the various formats.</p>
<p>In this tutorial, you’ll learn how to use the same Narwhals code to analyze data produced by the latest versions of two very common data libraries. You’ll also discover how Narwhals utilizes the efficiencies of your source data’s underlying library when analyzing your data. Furthermore, because Narwhals uses syntax that is a subset of Polars, you can reuse your existing Polars knowledge to quickly gain proficiency with Narwhals.</p>
<p>The table below will allow you to quickly decide whether or not Narwhals is for you:</p>
<div class="table-responsive">
<table class="table table-hover">
<thead>
<tr>
<th>Use Case</th>
<th class="text-center">Use Narwhals</th>
<th class="text-center">Use Another Tool</th>
</tr>
</thead>
<tbody>
<tr>
<td>You need to produce DataFrame-agnostic code.</td>
<td class="text-center">✅</td>
<td class="text-center">❌</td>
</tr>
<tr>
<td>You want to learn a new DataFrame library.</td>
<td class="text-center">❌</td>
<td class="text-center">✅</td>
</tr>
</tbody>
</table>
</div>
<p>Whether you’re wondering how to develop a Python library to cope with DataFrames from a range of common formats, or just curious to find out if this is even possible, this tutorial is for you. The Narwhals library could provide exactly what you’re looking for.</p>
<div class="alert alert-warning" role="alert">
<p><strong markdown>Get Your Code:</strong> <a href="https://realpython.com/bonus/narwhals-python-code/" class="alert-link" data-toggle="modal" data-target="#modal-narwhals-python-code" markdown>Click here to download the free sample code and data files</a> that you’ll use to work with Narwhals in Python.</p>
</div>
<div class="container border rounded text-wrap-pretty my-3">
<p class="my-3"><mark class="marker-highlight"><strong><span class="icon baseline" aria-hidden="true"><svg aria-hidden="true"><use href="/static/icons.5eccc70ec931.svg#@quiz"></use></svg></span> Take the Quiz:</strong></mark> Test your knowledge with our interactive “Writing DataFrame-Agnostic Python Code With Narwhals” quiz. You’ll receive a score upon completion to help you track your learning progress:</p>
<hr>
<div class="row my-3">
<div class="col-xs-12 col-sm-4 col-md-3 align-self-center">
<a href="/quizzes/narwhals-python/" tabindex="-1">
<div class="embed-responsive embed-responsive-16by9">
<img class="card-img-top m-0 p-0 embed-responsive-item rounded" style="object-fit: contain; background: #abe5b2;" alt="Writing DataFrame-Agnostic Python Code With Narwhals" src="https://files.realpython.com/media/Narwhals-Python-DataFrameInteroperability-for-Pandas-Polars--More_Watermarked.ff492f3b2207.jpg" width="1920" height="1080" srcset="/cdn-cgi/image/width=480,format=auto/https://files.realpython.com/media/Narwhals-Python-DataFrameInteroperability-for-Pandas-Polars--More_Watermarked.ff492f3b2207.jpg 480w, /cdn-cgi/image/width=640,format=auto/https://files.realpython.com/media/Narwhals-Python-DataFrameInteroperability-for-Pandas-Polars--More_Watermarked.ff492f3b2207.jpg 640w, /cdn-cgi/image/width=960,format=auto/https://files.realpython.com/media/Narwhals-Python-DataFrameInteroperability-for-Pandas-Polars--More_Watermarked.ff492f3b2207.jpg 960w, /cdn-cgi/image/width=1920,format=auto/https://files.realpython.com/media/Narwhals-Python-DataFrameInteroperability-for-Pandas-Polars--More_Watermarked.ff492f3b2207.jpg 1920w" sizes="(min-width: 1200px) 142px, (min-width: 1000px) 122px, (min-width: 780px) 112px, (min-width: 580px) 139px, calc(100vw - 62px)">
<div class="card-img-overlay d-flex align-items-center">
<div class="mx-auto">
<span class="text-light" style="opacity: 0.90;"><span class="icon baseline scale2x" aria-hidden="true"><svg aria-hidden="true"><use href="/static/icons.5eccc70ec931.svg#@quiz"></use></svg></span></span>
</div>
</div>
</div>
</a>
</div>
<div class="col">
<div class="mt-3 d-md-none"></div>
<p class="small text-muted mb-0"><strong>Interactive Quiz</strong></p>
<a href="/quizzes/narwhals-python/" class="stretched-link"><span class="my-0 h4">Writing DataFrame-Agnostic Python Code With Narwhals</span></a>
<p class="text-muted mb-0 small">If you're a Python library developer wondering how to write DataFrame-agnostic code, the Narwhals library is the solution you're looking for.</p>
</div>
</div>
</div>
<h2 id="get-ready-to-explore-narwhals">Get Ready to Explore Narwhals<a class="headerlink" href="#get-ready-to-explore-narwhals" title="Permanent link"></a></h2>
<p>Before you start, you’ll need to install Narwhals and have some data to play around with. You should also be familiar with the idea of a DataFrame. Although having an understanding of several DataFrame libraries isn’t mandatory, you’ll find a familiarity with <a href="https://realpython.com/polars-python/#dataframes-expressions-and-contexts">Polars’ expressions and contexts syntax</a> extremely useful. This is because Narwhals’ syntax is based on a subset of Polars’ syntax. However, Narwhals doesn’t replace Polars.</p>
<p>In this example, you’ll use data stored in the <code>presidents</code> <a href="https://en.wikipedia.org/wiki/Apache_Parquet">Parquet</a> file included in your downloadable materials.</p>
<p>This file contains the following six fields to describe <a href="https://en.wikipedia.org/wiki/List_of_presidents_of_the_United_States">United States presidents</a>:</p>
<div class="table-responsive">
<table class="table table-hover">
<thead>
<tr>
<th>Heading</th>
<th>Meaning</th>
</tr>
</thead>
<tbody>
<tr>
<td><code>last_name</code></td>
<td>The president’s last name</td>
</tr>
<tr>
<td><code>first_name</code></td>
<td>The president’s first name</td>
</tr>
<tr>
<td><code>term_start</code></td>
<td>Start of the presidential term</td>
</tr>
<tr>
<td><code>term_end</code></td>
<td>End of the presidential term</td>
</tr>
<tr>
<td><code>party_name</code></td>
<td>The president’s political party</td>
</tr>
<tr>
<td><code>century</code></td>
<td>Century the president’s term started</td>
</tr>
</tbody>
</table>
</div>
<p>To work through this tutorial, you’ll need to install the <a href="https://pandas.pydata.org/docs/">pandas</a>, <a href="https://pola.rs/">Polars</a>, <a href="https://pyarrow.readthedocs.io/en/latest/">PyArrow</a>, and <a href="https://narwhals-dev.github.io/narwhals/">Narwhals</a> libraries:</p>
<code-block class="mb-3" aria-label="Code block" data-syntax-language="console" data-is-repl="true">
<div class="codeblock__header codeblock--yellow">
<span class="mr-2 noselect" aria-label="Language">Shell</span>
<div class="noselect">
<span class="codeblock__output-toggle" title="Toggle prompts and output" role="button"><span class="icon baseline js-codeblock-output-on codeblock__header--icon-lower" aria-hidden="true"><svg aria-hidden="true"><use href="/static/icons.5eccc70ec931.svg#regular--rectangle-terminal"></use></svg></span></span>
</div>
</div>
<div class="codeblock__contents">
<div class="highlight highlight--with-header"><pre><span></span><code><span class="gp">$ </span>python<span class="w"> </span>-m<span class="w"> </span>pip<span class="w"> </span>install<span class="w"> </span>pandas<span class="w"> </span>polars<span class="w"> </span>pyarrow<span class="w"> </span>narwhals
</code></pre></div>
<button class="codeblock__copy btn btn-outline-secondary border m-1 px-1 d-hover-only" title="Copy to clipboard"><span class="icon baseline" aria-hidden="true"><svg aria-hidden="true"><use href="/static/icons.5eccc70ec931.svg#@copy"></use></svg></span></button>
</div>
</code-block>
<p>A key feature of Narwhals is that it’s DataFrame-agnostic, meaning your code can work with several formats. But you still need both Polars and pandas because Narwhals will use them to process the data you pass to it. You’ll also need them to create your DataFrames to pass to Narwhals to begin with.</p>
<p>You installed the PyArrow library to correctly read the Parquet files. Finally, you installed Narwhals itself.</p>
<p>With everything installed, make sure you create the project’s folder and place your downloaded <code>presidents.parquet</code> file inside it. You might also like to add both the <code>books.parquet</code> and <code>authors.parquet</code> files as well. You’ll need them later. </p>
<p>With that lot done, you’re good to go!</p>
<h2 id="understand-how-narwhals-works">Understand How Narwhals Works<a class="headerlink" href="#understand-how-narwhals-works" title="Permanent link"></a></h2>
<p>The documentation describes Narwhals as follows:</p>
<blockquote>
<p>Extremely lightweight and extensible compatibility layer between dataframe libraries! (<a href="https://narwhals-dev.github.io/narwhals/">Source</a>)</p>
</blockquote>
<p>Narwhals is <strong>lightweight</strong> because it wraps the original DataFrame in its own object ecosystem while still using the source DataFrame’s library to process it. Any data passed into it for processing doesn’t need to be duplicated, removing an otherwise resource-intensive and time-consuming operation.</p>
<p>Narwhals is also <strong>extensible</strong>. For example, you can write Narwhals code to work with the full API of the following libraries:</p>
<ul>
<li><a href="https://github.com/rapidsai/cudf">cuDF</a></li>
<li><a href="https://github.com/modin-project/modin">Modin</a></li>
<li><a href="https://pandas.pydata.org/">pandas</a></li>
<li><a href="https://pola.rs/">Polars</a></li>
<li><a href="https://arrow.apache.org/docs/python/">PyArrow</a></li>
</ul>
<p>It also supports the lazy API of the following:</p>
</div><h2><a href="https://realpython.com/narwhals-python/?utm_source=realpython&utm_medium=rss">Read the full article at https://realpython.com/narwhals-python/ »</a></h2>
<hr />
<p><em>[ Improve Your Python With 🐍 Python Tricks 💌 – Get a short & sweet Python Trick delivered to your inbox every couple of days. <a href="https://realpython.com/python-tricks/?utm_source=realpython&utm_medium=rss&utm_campaign=footer">>> Click here to learn more and see examples</a> ]</em></p>
Quiz: Writing DataFrame-Agnostic Python Code With Narwhals
https://realpython.com/quizzes/narwhals-python/
2025-12-15T12:00:00+00:00
If you're a Python library developer wondering how to write DataFrame-agnostic code, the Narwhals library is the solution you're looking for.
<p>In this quiz, you’ll test your understanding of what the Narwhals library offers you.</p>
<p>By working through this quiz, you’ll revisit many of the concepts presented in the <a href="https://realpython.com/narwhals-python/">Writing DataFrame-Agnostic Code With Narwhals </a> tutorial.</p>
<p>Remember, also, the <a href="https://narwhals-dev.github.io/narwhals/">official documentation</a> is a great reference source for the latest Narwhals developments.</p>
<hr />
<p><em>[ Improve Your Python With 🐍 Python Tricks 💌 – Get a short & sweet Python Trick delivered to your inbox every couple of days. <a href="https://realpython.com/python-tricks/?utm_source=realpython&utm_medium=rss&utm_campaign=footer">>> Click here to learn more and see examples</a> ]</em></p>
Python Inner Functions: What Are They Good For?
https://realpython.com/inner-functions-what-are-they-good-for/
2025-12-10T14:00:00+00:00
Learn how to create inner functions in Python to access nonlocal names, build stateful closures, and create decorators.
<div><p>Python inner functions are those you define inside other functions to access <a href="/ref/keywords/nonlocal/" class="ref-link"><code>nonlocal</code></a> names and bundle logic with its surrounding state. In this tutorial, you’ll learn how to create inner helper functions, build closures that retain state across calls, and implement decorators that modify the behavior or existing callables without changing the original implementation.</p>
<p><strong>By the end of this tutorial, you’ll understand that:</strong></p>
<ul>
<li>Inner functions access <strong>nonlocal names</strong> from the enclosing scope, so you pass data in once and reuse it across calls.</li>
<li>You can replace an <strong>inner helper function</strong> with a <strong>non-public</strong> function to enable code reuse.</li>
<li>You can create a <strong>closure</strong> by returning the inner function without calling it, which preserves the captured environment.</li>
<li>You can <strong>modify the captured state</strong> by declaring nonlocal variables that point to <strong>mutable objects</strong>.</li>
<li>You craft <strong>decorators</strong> with nested functions that wrap a callable and extend its behavior transparently.</li>
</ul>
<p>You will now move through focused examples that feature encapsulated helpers, stateful closures, and decorator patterns, allowing you to apply each technique with confidence in real Python projects.</p>
<div class="alert alert-warning" role="alert">
<p><strong markdown>Get Your Code:</strong> <a href="https://realpython.com/bonus/python-inner-functions-code/" class="alert-link" data-toggle="modal" data-target="#modal-python-inner-functions-code" markdown>Click here to download the free sample code</a> to practice inner functions in Python.</p>
</div>
<div class="container border rounded text-wrap-pretty my-3">
<p class="my-3"><mark class="marker-highlight"><strong><span class="icon baseline" aria-hidden="true"><svg aria-hidden="true"><use href="/static/icons.5eccc70ec931.svg#@quiz"></use></svg></span> Take the Quiz:</strong></mark> Test your knowledge with our interactive “Python Inner Functions: What Are They Good For?” quiz. You’ll receive a score upon completion to help you track your learning progress:</p>
<hr>
<div class="row my-3">
<div class="col-xs-12 col-sm-4 col-md-3 align-self-center">
<a href="/quizzes/inner-functions-what-are-they-good-for/" tabindex="-1">
<div class="embed-responsive embed-responsive-16by9">
<img class="card-img-top m-0 p-0 embed-responsive-item rounded" style="object-fit: contain; background: #ffc873;" alt="Python Inner Functions" src="https://files.realpython.com/media/Inner-Functions-What-Are-They-Good-For_Watermarked.995d44a06cdd.jpg" width="1920" height="1080" srcset="/cdn-cgi/image/width=480,format=auto/https://files.realpython.com/media/Inner-Functions-What-Are-They-Good-For_Watermarked.995d44a06cdd.jpg 480w, /cdn-cgi/image/width=640,format=auto/https://files.realpython.com/media/Inner-Functions-What-Are-They-Good-For_Watermarked.995d44a06cdd.jpg 640w, /cdn-cgi/image/width=960,format=auto/https://files.realpython.com/media/Inner-Functions-What-Are-They-Good-For_Watermarked.995d44a06cdd.jpg 960w, /cdn-cgi/image/width=1920,format=auto/https://files.realpython.com/media/Inner-Functions-What-Are-They-Good-For_Watermarked.995d44a06cdd.jpg 1920w" sizes="(min-width: 1200px) 142px, (min-width: 1000px) 122px, (min-width: 780px) 112px, (min-width: 580px) 139px, calc(100vw - 62px)">
<div class="card-img-overlay d-flex align-items-center">
<div class="mx-auto">
<span class="text-light" style="opacity: 0.90;"><span class="icon baseline scale2x" aria-hidden="true"><svg aria-hidden="true"><use href="/static/icons.5eccc70ec931.svg#@quiz"></use></svg></span></span>
</div>
</div>
</div>
</a>
</div>
<div class="col">
<div class="mt-3 d-md-none"></div>
<p class="small text-muted mb-0"><strong>Interactive Quiz</strong></p>
<a href="/quizzes/inner-functions-what-are-they-good-for/" class="stretched-link"><span class="my-0 h4">Python Inner Functions: What Are They Good For?</span></a>
<p class="text-muted mb-0 small">Test inner functions, closures, nonlocal, and decorators in Python. Build confidence and learn to keep state across calls. Try the quiz now.</p>
</div>
</div>
</div>
<h2 id="creating-functions-within-functions-in-python">Creating Functions Within Functions in Python<a class="headerlink" href="#creating-functions-within-functions-in-python" title="Permanent link"></a></h2>
<p>A <a href="/ref/glossary/function/" class="ref-link">function</a> defined inside another function is known as an <strong>inner function</strong> or a <strong>nested function</strong>. Yes, in Python, you can define a function within another function. This type of function can access names defined in the <a href="https://realpython.com/python-scope-legb-rule/#the-enclosing-scope">enclosing scope</a>.</p>
<p>Here’s an example of how to create an inner function in Python:</p>
<code-block class="mb-3" aria-label="Code block" data-syntax-language="pycon" data-is-repl="true">
<div class="codeblock__header codeblock--blue">
<span class="mr-2 noselect" aria-label="Language">Python</span>
<div class="noselect">
<span class="codeblock__output-toggle" title="Toggle prompts and output" role="button"><span class="icon baseline js-codeblock-output-on codeblock__header--icon-lower" aria-hidden="true"><svg aria-hidden="true"><use href="/static/icons.5eccc70ec931.svg#regular--rectangle-terminal"></use></svg></span></span>
</div>
</div>
<div class="codeblock__contents">
<div class="highlight highlight--with-header"><pre><span></span><code><span class="gp">>>> </span><span class="k">def</span><span class="w"> </span><span class="nf">outer_func</span><span class="p">():</span>
<span class="gp">... </span> <span class="k">def</span><span class="w"> </span><span class="nf">inner_func</span><span class="p">():</span>
<span class="gp">... </span> <span class="nb">print</span><span class="p">(</span><span class="s2">"Hello, World!"</span><span class="p">)</span>
<span class="gp">... </span> <span class="n">inner_func</span><span class="p">()</span>
<span class="gp">...</span>
<span class="gp">>>> </span><span class="n">outer_func</span><span class="p">()</span>
<span class="go">Hello, World!</span>
</code></pre></div>
<button class="codeblock__copy btn btn-outline-secondary border m-1 px-1 d-hover-only" title="Copy to clipboard"><span class="icon baseline" aria-hidden="true"><svg aria-hidden="true"><use href="/static/icons.5eccc70ec931.svg#@copy"></use></svg></span></button>
</div>
</code-block>
<p>In this example, you define <code>inner_func()</code> inside <code>outer_func()</code> to <a href="https://realpython.com/python-print/">print</a> the <code>Hello, World!</code> message to the screen. To do that, you call <code>inner_func()</code> on the last line of <code>outer_func()</code>. This is the quickest way to write and use an inner function in Python.</p>
<p>Inner functions provide several interesting possibilities beyond what you see in the example above. The core feature of inner functions is their ability to access variables and objects from their enclosing function even after that function has returned. The enclosing function provides a <a href="https://realpython.com/python-namespaces-scope/">namespace</a> that is accessible to the inner function:</p>
<code-block class="mb-3" aria-label="Code block" data-syntax-language="pycon" data-is-repl="true">
<div class="codeblock__header codeblock--blue">
<span class="mr-2 noselect" aria-label="Language">Python</span>
<div class="noselect">
<span class="codeblock__output-toggle" title="Toggle prompts and output" role="button"><span class="icon baseline js-codeblock-output-on codeblock__header--icon-lower" aria-hidden="true"><svg aria-hidden="true"><use href="/static/icons.5eccc70ec931.svg#regular--rectangle-terminal"></use></svg></span></span>
</div>
</div>
<div class="codeblock__contents">
<div class="highlight highlight--with-header"><pre><span></span><code><span class="gp">>>> </span><span class="k">def</span><span class="w"> </span><span class="nf">outer_func</span><span class="p">(</span><span class="n">who</span><span class="p">):</span>
<span class="gp">... </span> <span class="k">def</span><span class="w"> </span><span class="nf">inner_func</span><span class="p">():</span>
<span class="gp">... </span> <span class="nb">print</span><span class="p">(</span><span class="sa">f</span><span class="s2">"Hello, </span><span class="si">{</span><span class="n">who</span><span class="si">}</span><span class="s2">"</span><span class="p">)</span>
<span class="gp">... </span> <span class="n">inner_func</span><span class="p">()</span>
<span class="gp">...</span>
<span class="gp">>>> </span><span class="n">outer_func</span><span class="p">(</span><span class="s2">"World!"</span><span class="p">)</span>
<span class="go">Hello, World!</span>
</code></pre></div>
<button class="codeblock__copy btn btn-outline-secondary border m-1 px-1 d-hover-only" title="Copy to clipboard"><span class="icon baseline" aria-hidden="true"><svg aria-hidden="true"><use href="/static/icons.5eccc70ec931.svg#@copy"></use></svg></span></button>
</div>
</code-block>
<p>Note how you can pass a <a href="https://realpython.com/python-strings/">string</a> as an <a href="/ref/glossary/argument/" class="ref-link">argument</a> to <code>outer_func()</code>, and <code>inner_func()</code> can access that argument through the name <code>who</code>. This name is defined in the <a href="https://realpython.com/python-scope-legb-rule/#the-local-scope">local scope</a> of <code>outer_func()</code>. The names defined in the local scope of an outer function are <strong>nonlocal names</strong> from the inner function’s point of view.</p>
<p>Here’s an example of a more realistic inner function:</p>
<code-block class="mb-3" aria-label="Code block" data-syntax-language="pycon" data-is-repl="true">
<div class="codeblock__header codeblock--blue">
<span class="mr-2 noselect" aria-label="Language">Python</span>
<div class="noselect">
<span class="codeblock__output-toggle" title="Toggle prompts and output" role="button"><span class="icon baseline js-codeblock-output-on codeblock__header--icon-lower" aria-hidden="true"><svg aria-hidden="true"><use href="/static/icons.5eccc70ec931.svg#regular--rectangle-terminal"></use></svg></span></span>
</div>
</div>
<div class="codeblock__contents">
<div class="highlight highlight--with-header"><pre><span></span><code><span class="gp">>>> </span><span class="k">def</span><span class="w"> </span><span class="nf">factorial</span><span class="p">(</span><span class="n">number</span><span class="p">):</span>
<span class="gp">... </span> <span class="k">if</span> <span class="ow">not</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">number</span><span class="p">,</span> <span class="nb">int</span><span class="p">):</span>
<span class="gp">... </span> <span class="k">raise</span> <span class="ne">TypeError</span><span class="p">(</span><span class="s2">"number must be an integer"</span><span class="p">)</span>
<span class="gp">... </span> <span class="k">if</span> <span class="n">number</span> <span class="o"><</span> <span class="mi">0</span><span class="p">:</span>
<span class="gp">... </span> <span class="k">raise</span> <span class="ne">ValueError</span><span class="p">(</span><span class="s2">"number must be zero or positive"</span><span class="p">)</span>
<span class="gp">...</span>
<span class="hll"><span class="gp">... </span> <span class="k">def</span><span class="w"> </span><span class="nf">inner_factorial</span><span class="p">(</span><span class="n">number</span><span class="p">):</span>
</span><span class="gp">... </span> <span class="k">if</span> <span class="n">number</span> <span class="o"><=</span> <span class="mi">1</span><span class="p">:</span>
<span class="gp">... </span> <span class="k">return</span> <span class="mi">1</span>
<span class="gp">... </span> <span class="k">return</span> <span class="n">number</span> <span class="o">*</span> <span class="n">inner_factorial</span><span class="p">(</span><span class="n">number</span> <span class="o">-</span> <span class="mi">1</span><span class="p">)</span>
<span class="gp">... </span> <span class="k">return</span> <span class="n">inner_factorial</span><span class="p">(</span><span class="n">number</span><span class="p">)</span>
<span class="gp">...</span>
<span class="gp">>>> </span><span class="n">factorial</span><span class="p">(</span><span class="mi">4</span><span class="p">)</span>
<span class="go">24</span>
</code></pre></div>
<button class="codeblock__copy btn btn-outline-secondary border m-1 px-1 d-hover-only" title="Copy to clipboard"><span class="icon baseline" aria-hidden="true"><svg aria-hidden="true"><use href="/static/icons.5eccc70ec931.svg#@copy"></use></svg></span></button>
</div>
</code-block>
<p>In <code>factorial()</code>, you first validate the input data to ensure that the user provides an integer that is equal to or greater than zero. Then, you define a <a href="/ref/glossary/recursion/" class="ref-link">recursive</a> inner function called <code>inner_factorial()</code>. This function performs the factorial calculation and <a href="https://realpython.com/python-return-statement/">returns</a> the result. The final step is to call <code>inner_factorial()</code>.</p>
<div class="alert alert-primary" role="alert">
<p><strong>Note:</strong> For a more detailed discussion on recursion and recursive functions, check out <a href="https://realpython.com/python-thinking-recursively/">Thinking Recursively in Python</a> and <a href="https://realpython.com/python-recursion/">Recursion in Python: An Introduction</a>.</p>
</div>
<p>An advantage of using the pattern in the example above is that you perform all the argument validation in the outer function, so you can skip error checking in the inner function and focus on the computation at hand.</p>
<h2 id="using-inner-functions-in-python">Using Inner Functions in Python<a class="headerlink" href="#using-inner-functions-in-python" title="Permanent link"></a></h2>
<p>The use cases of Python inner functions are varied. You can use them to provide <a href="https://en.wikipedia.org/wiki/Encapsulation_(computer_programming)">encapsulation</a>, hiding your functions from external access. You can also write quick helper inner functions. Finally, you can use inner functions to create <a href="https://realpython.com/python-closure/">closures</a> and <a href="https://realpython.com/primer-on-python-decorators/">decorators</a>.</p>
<p>In this section, you’ll learn about the former two use cases of inner functions, and in later sections, you’ll learn how to create <a href="#retaining-state-in-a-closure">closures</a> and <a href="#building-decorators-with-nested-functions-in-python">decorators</a>.</p>
<h3 id="providing-encapsulation">Providing Encapsulation<a class="headerlink" href="#providing-encapsulation" title="Permanent link"></a></h3>
<p>A common use case of inner functions arises when you need to protect or hide a given function from everything happening outside of it, so that the function is completely hidden from the global <a href="https://realpython.com/python-scope-legb-rule/">scope</a>. This type of behavior is known as <a href="/ref/glossary/encapsulation/" class="ref-link"><strong>encapsulation</strong></a>.</p>
<p>Here’s an example that showcases the concept:</p>
</div><h2><a href="https://realpython.com/inner-functions-what-are-they-good-for/?utm_source=realpython&utm_medium=rss">Read the full article at https://realpython.com/inner-functions-what-are-they-good-for/ »</a></h2>
<hr />
<p><em>[ Improve Your Python With 🐍 Python Tricks 💌 – Get a short & sweet Python Trick delivered to your inbox every couple of days. <a href="https://realpython.com/python-tricks/?utm_source=realpython&utm_medium=rss&utm_campaign=footer">>> Click here to learn more and see examples</a> ]</em></p>
Quiz: Python Inner Functions: What Are They Good For?
https://realpython.com/quizzes/inner-functions-what-are-they-good-for/
2025-12-10T12:00:00+00:00
Test inner functions, closures, nonlocal, and decorators in Python. Build confidence and learn to keep state across calls. Try the quiz now.
<p>In this quiz, you’ll test your understanding of the <a href="https://realpython.com/inner-functions-what-are-they-good-for/">Python Inner Functions: What Are They Good For?</a> tutorial.</p>
<p>By working through this quiz, you’ll revisit how inner functions work with enclosing scopes, when to use <code>nonlocal</code> to update captured state, how closures retain data across calls, and how decorators wrap a callable to extend behavior.</p>
<p>You’ll apply these ideas to organize helpers, reuse state, and write clear, maintainable functions in real projects.</p>
<hr />
<p><em>[ Improve Your Python With 🐍 Python Tricks 💌 – Get a short & sweet Python Trick delivered to your inbox every couple of days. <a href="https://realpython.com/python-tricks/?utm_source=realpython&utm_medium=rss&utm_campaign=footer">>> Click here to learn more and see examples</a> ]</em></p>
Using Functional Programming in Python
https://realpython.com/courses/using-functional-programming/
2025-12-09T14:00:00+00:00
Boost your Python skills with a quick dive into functional programming: what it is, how Python supports it, and why it matters.
<p><strong>Functional programming</strong> is a programming paradigm in which the primary method of computation is the evaluation of functions. But how does Python support functional programming?</p>
<p><strong>In this video course, you’ll learn:</strong></p>
<ul>
<li>What the <strong>functional programming</strong> paradigm entails</li>
<li>What it means to say that <strong>functions</strong> are <strong>first-class citizens</strong> in Python</li>
<li>How to define <strong>anonymous functions</strong> with the <strong><code>lambda</code></strong> keyword</li>
<li>How to implement functional code using <strong><code>map()</code></strong>, <strong><code>filter()</code></strong>, and <strong><code>reduce()</code></strong></li>
</ul>
<hr />
<p><em>[ Improve Your Python With 🐍 Python Tricks 💌 – Get a short & sweet Python Trick delivered to your inbox every couple of days. <a href="https://realpython.com/python-tricks/?utm_source=realpython&utm_medium=rss&utm_campaign=footer">>> Click here to learn more and see examples</a> ]</em></p>
Lazy Imports Land in Python and Other Python News for December 2025
https://realpython.com/python-news-december-2025/
2025-12-08T14:00:00+00:00
PEP 810 brings lazy imports to Python 3.15, PyPI tightens 2FA security, and Django 6.0 reaches release candidate. Catch up on all the important Python news!
<div><p>A lot happened last month in the world of Python! The core developers pushed ahead on <strong>Python 3.15</strong>, accepting <strong>PEP 810</strong> to bring explicit lazy imports to the language. PyPI tightened account security, <strong>Django 6.0</strong> landed with a slew of new features while celebrating twenty years of releases, and the <strong>Python Software Foundation (PSF)</strong> laid out its financial outlook and kicked off a year-end fundraiser.</p>
<p>Let’s dive into the biggest <strong>Python news</strong> from the past month!</p>
<div class="alert alert-warning" role="alert">
<p><strong markdown>Join Now:</strong> <a href="https://realpython.com/bonus/newsletter/" class="alert-link" data-toggle="modal" data-target="#modal-newsletter" markdown>Click here to join the Real Python Newsletter</a> and you’ll never miss another Python tutorial, course, or news update.</p>
</div>
<h2 id="python-releases-and-pep-highlights">Python Releases and PEP Highlights<a class="headerlink" href="#python-releases-and-pep-highlights" title="Permanent link"></a></h2>
<p>Last month brought forward movement on Python 3.15, with a new alpha release and a major <a href="/ref/glossary/pep/" class="ref-link">PEP</a> acceptance. Windows users also got an update to the new Python install manager that’s set to replace the traditional installers.</p>
<h3 id="python-3150-alpha-2-keeps-the-train-moving">Python 3.15.0 Alpha 2 Keeps the Train Moving<a class="headerlink" href="#python-3150-alpha-2-keeps-the-train-moving" title="Permanent link"></a></h3>
<p>Python 3.15’s second alpha, <a href="https://www.python.org/downloads/release/python-3150a2/">3.15.0a2</a>, arrived on November 19 as part of the language’s regular annual release cadence. It’s an early developer preview that isn’t intended for production, but it shows how 3.15 is shaping up and gives library authors something concrete to test against.</p>
<p>Like <a href="https://realpython.com/python-news-november-2025/#python-315-alpha-1-released">alpha 1</a>, this release is still relatively small in user-visible features, but it continues the work of:</p>
<ul>
<li>Making <strong>UTF-8 the default text encoding</strong> for files that don’t specify an encoding, via <a href="https://peps.python.org/pep-0686/">PEP 686</a></li>
<li>Providing a <strong>dedicated profiling API</strong> designed to work better with modern profilers and monitoring tools, via <a href="https://peps.python.org/pep-0799/">PEP 799</a></li>
<li>Exposing lower-level C APIs for creating <code>bytes</code> objects more efficiently, via <a href="https://peps.python.org/pep-0782/">PEP 782</a></li>
</ul>
<p>If you maintain packages, now is a good time to <a href="https://realpython.com/python-pre-release/">start running tests against the alphas</a> in a separate environment so you can catch regressions early.</p>
<p>You can always confirm which Python you’re running with <code>python -VV</code>:</p>
<code-block class="mb-3" aria-label="Code block" data-syntax-language="console" data-is-repl="true">
<div class="codeblock__header codeblock--yellow">
<span class="mr-2 noselect" aria-label="Language">Shell</span>
<div class="noselect">
<span class="codeblock__output-toggle" title="Toggle prompts and output" role="button"><span class="icon baseline js-codeblock-output-on codeblock__header--icon-lower" aria-hidden="true"><svg aria-hidden="true"><use href="/static/icons.5eccc70ec931.svg#regular--rectangle-terminal"></use></svg></span></span>
</div>
</div>
<div class="codeblock__contents">
<div class="highlight highlight--with-header"><pre><span></span><code><span class="gp">$ </span>python<span class="w"> </span>-VV
<span class="go">Python 3.15.0a2 (main, Nov 19 2025, 10:42:00) [GCC ...]</span>
</code></pre></div>
<button class="codeblock__copy btn btn-outline-secondary border m-1 px-1 d-hover-only" title="Copy to clipboard"><span class="icon baseline" aria-hidden="true"><svg aria-hidden="true"><use href="/static/icons.5eccc70ec931.svg#@copy"></use></svg></span></button>
</div>
</code-block>
<p>Just remember to keep the alpha builds isolated from your everyday projects!</p>
<h3 id="pep-810-accepted-explicit-lazy-imports">PEP 810 Accepted: Explicit Lazy Imports<a class="headerlink" href="#pep-810-accepted-explicit-lazy-imports" title="Permanent link"></a></h3>
<p>One of the month’s most consequential decisions for the language was the acceptance of <a href="https://peps.python.org/pep-0810/">PEP 810 – Explicit lazy imports</a>, which you may have read about in <a href="https://realpython.com/python-news-november-2025/#pep-810-drafted-explicit-lazy-imports">last month’s news</a>. The <a href="/ref/glossary/python-steering-council/" class="ref-link">Python Steering Council</a> accepted the proposal on November 3, only a month after its formal creation on October 2. With the PEP moving from <em>Draft</em> to <em>Accepted</em>, it’s now targeted for inclusion in Python 3.15!</p>
<div class="alert alert-primary" role="alert">
<p><strong>Note:</strong> One of the PEP’s authors, <a href="https://realpython.com/search?kind=podcast&q=pablo+galindo+salgado">Pablo Galindo Salgado</a>, has been a frequent guest on the <a href="https://realpython.com/podcasts/rpp/">Real Python Podcast</a>.</p>
</div>
<p>PEP 810 introduces new syntax for <a href="https://realpython.com/python-import/">imports</a> that are evaluated only when first used, rather than at module import time. At a high level, you’ll be able to write:</p>
<code-block class="mb-3" aria-label="Code block" data-syntax-language="python">
<div class="codeblock__header codeblock--blue">
<span class="mr-2 noselect" aria-label="Language">Python</span>
<div class="noselect">
</div>
</div>
<div class="codeblock__contents">
<div class="highlight highlight--with-header"><pre><span></span><code><span class="n">lazy</span> <span class="kn">import</span><span class="w"> </span><span class="nn">json</span>
<span class="k">def</span><span class="w"> </span><span class="nf">parse</span><span class="p">():</span>
<span class="k">return</span> <span class="n">json</span><span class="o">.</span><span class="n">loads</span><span class="p">(</span><span class="n">payload</span><span class="p">)</span>
</code></pre></div>
<button class="codeblock__copy btn btn-outline-secondary border m-1 px-1 d-hover-only" title="Copy to clipboard"><span class="icon baseline" aria-hidden="true"><svg aria-hidden="true"><use href="/static/icons.5eccc70ec931.svg#@copy"></use></svg></span></button>
</div>
</code-block>
<p>In this example, Python loads the <code>json</code> module only if <code>parse()</code> runs.</p>
<p>The goals of explicit lazy imports are to:</p>
<ul>
<li><strong>Improve startup time</strong> for large applications with many rarely used imports</li>
<li><strong>Break tricky import cycles</strong> without resorting to local imports inside functions</li>
<li>Give frameworks and tools a <strong>clear, explicit way to defer expensive imports</strong></li>
</ul>
<p>Lazy imports are entirely opt-in, meaning that only imports marked as <code>lazy</code> change their behavior. The PEP is also careful to spell out how lazy modules interact with attributes like <a href="https://realpython.com/python-all-attribute/"><code>__all__</code></a>, <a href="/ref/glossary/exception/" class="ref-link">exception</a> reporting, and tools such as <a href="/ref/glossary/debugging/" class="ref-link">debuggers</a>.</p>
<div class="alert alert-primary" role="alert">
<p><strong>Note:</strong> The implementation work is still underway, so you won’t see the new syntax in 3.15.0a2 yet.</p>
</div>
<p>If you maintain a framework, CLI tool, or large application, it’s worth reading through the PEP and thinking about where lazy imports could simplify your startup path or trim cold-start latency.</p>
<h3 id="pythons-new-install-manager-moves-forward-on-windows">Python’s New Install Manager Moves Forward on Windows<a class="headerlink" href="#pythons-new-install-manager-moves-forward-on-windows" title="Permanent link"></a></h3>
</div><h2><a href="https://realpython.com/python-news-december-2025/?utm_source=realpython&utm_medium=rss">Read the full article at https://realpython.com/python-news-december-2025/ »</a></h2>
<hr />
<p><em>[ Improve Your Python With 🐍 Python Tricks 💌 – Get a short & sweet Python Trick delivered to your inbox every couple of days. <a href="https://realpython.com/python-tricks/?utm_source=realpython&utm_medium=rss&utm_campaign=footer">>> Click here to learn more and see examples</a> ]</em></p>
The Real Python Podcast – Episode #276: Exploring Quantum Computing & Python Frameworks
https://realpython.com/podcasts/rpp/276/
2025-12-05T12:00:00+00:00
What are the recent advances in the field of quantum computing and high-performance computing? And what Python tools can you use to develop programs that run on quantum computers? This week on the show, Real Python author Negar Vahid discusses her tutorial, "Quantum Computing Basics With Qiskit."
<p>What are the recent advances in the field of quantum computing and high-performance computing? And what Python tools can you use to develop programs that run on quantum computers? This week on the show, Real Python author Negar Vahid discusses her tutorial, "Quantum Computing Basics With Qiskit."</p>
<hr />
<p><em>[ Improve Your Python With 🐍 Python Tricks 💌 – Get a short & sweet Python Trick delivered to your inbox every couple of days. <a href="https://realpython.com/python-tricks/?utm_source=realpython&utm_medium=rss&utm_campaign=footer">>> Click here to learn more and see examples</a> ]</em></p>
How to Use Google's Gemini CLI for AI Code Assistance
https://realpython.com/how-to-use-gemini-cli/
2025-12-03T14:00:00+00:00
Learn how to use Gemini CLI to bring Google's AI-powered coding assistance directly into your terminal to help you analyze and fix code.
<div><p>This tutorial will teach you how to use <a href="/ref/ai-coding-tools/gemini-cli/" class="ref-link">Gemini CLI</a> to bring Google’s AI-powered coding assistance directly into your terminal. After you authenticate with your Google account, this tool will be ready to help you analyze code, identify bugs, and suggest fixes—all without leaving your familiar development environment:</p>
<figure>
<div class="embed-responsive embed-responsive-16by9 rounded mb-3 border">
<iframe loading="lazy" class="embed-responsive-item" src="https://player.vimeo.com/video/1133218312?background=1" frameborder="0" allow="fullscreen" allowfullscreen></iframe>
</div>
<figcaption class="figure-caption text-center">Gemini CLI</figcaption>
</figure>
<p>Imagine <a href="/ref/glossary/debugging/" class="ref-link">debugging</a> code without switching between your <a href="/ref/glossary/console/" class="ref-link">console</a> and browser, or picture getting instant explanations for unfamiliar projects. Like other command-line AI assistants, Google’s Gemini CLI brings AI-powered coding assistance directly into your command line, allowing you to stay focused in your development workflow.</p>
<p>Whether you’re troubleshooting a stubborn bug, understanding legacy code, or generating documentation, this tool acts as an intelligent pair-programming partner that understands your codebase’s context.</p>
<p>You’re about to install Gemini CLI, authenticate with Google’s free tier, and put it to work on an actual Python project. You’ll discover how natural language queries can help you understand code faster and catch bugs that might slip past manual review.</p>
<h2 id="prerequisites">Prerequisites<a class="headerlink" href="#prerequisites" title="Permanent link"></a></h2>
<p>To follow along with this tutorial, you’ll need the following:</p>
<ul>
<li><strong>Google Account:</strong> A personal <a href="https://www.google.com/account/about/">Google account</a> is required to use Gemini CLI’s free tier, which offers one thousand requests per day and sixty requests per minute at no charge.</li>
<li><strong>Python 3.12 or Higher:</strong> You’ll work with a Python <a href="https://realpython.com/command-line-interfaces-python-argparse/">command-line application</a> to demonstrate Gemini CLI’s capabilities. If you haven’t already, <a href="https://realpython.com/installing-python/">install Python</a> on your system, making sure the minimum version is <a href="https://realpython.com/python312-new-features/">Python 3.12</a>.</li>
<li><strong>Node.js 20 or Higher:</strong> Gemini CLI is distributed through npm, Node.js’s package manager. You’ll verify your Node.js installation in the next section.</li>
</ul>
<p>Because Gemini CLI is a command-line tool, you should feel comfortable navigating your <a href="https://realpython.com/terminal-commands/">terminal</a> and running basic shell commands.</p>
<p>Go ahead and download the supporting materials to get the Python project you’ll be working with throughout this tutorial:</p>
<div class="alert alert-warning" role="alert">
<p><strong markdown>Get Your Code:</strong> <a href="https://realpython.com/bonus/how-to-use-gemini-cli-code/" class="alert-link" data-toggle="modal" data-target="#modal-how-to-use-gemini-cli-code" markdown>Click here to download the free sample code</a> that you’ll use to take Google’s Gemini CLI for a spin.</p>
</div>
<p>Once you’ve extracted the files, you’ll find a <code>todolist/</code> directory containing a complete Python CLI application, which is similar to the <a href="https://realpython.com/python-typer-cli/">to-do app</a> covered in another tutorial. This project will serve as your testing ground for Gemini CLI’s code analysis and debugging features.</p>
<div class="container border rounded text-wrap-pretty my-3">
<p class="my-3"><mark class="marker-highlight"><strong><span class="icon baseline" aria-hidden="true"><svg aria-hidden="true"><use href="/static/icons.5eccc70ec931.svg#@quiz"></use></svg></span> Take the Quiz:</strong></mark> Test your knowledge with our interactive “How to Use Google's Gemini CLI for AI Code Assistance” quiz. You’ll receive a score upon completion to help you track your learning progress:</p>
<hr>
<div class="row my-3">
<div class="col-xs-12 col-sm-4 col-md-3 align-self-center">
<a href="/quizzes/how-to-use-gemini-cli/" tabindex="-1">
<div class="embed-responsive embed-responsive-16by9">
<img class="card-img-top m-0 p-0 embed-responsive-item rounded" style="object-fit: contain; background: #abe0e6;" alt="How to Use Google's Gemini CLI for AI Code Assistance" src="https://files.realpython.com/media/How-to-Use-Gemini-CLI-to-Work-with-LLMs-in-Your-Terminal_Watermarked.bcf2fe57f200.jpg" width="1920" height="1080" srcset="/cdn-cgi/image/width=480,format=auto/https://files.realpython.com/media/How-to-Use-Gemini-CLI-to-Work-with-LLMs-in-Your-Terminal_Watermarked.bcf2fe57f200.jpg 480w, /cdn-cgi/image/width=640,format=auto/https://files.realpython.com/media/How-to-Use-Gemini-CLI-to-Work-with-LLMs-in-Your-Terminal_Watermarked.bcf2fe57f200.jpg 640w, /cdn-cgi/image/width=960,format=auto/https://files.realpython.com/media/How-to-Use-Gemini-CLI-to-Work-with-LLMs-in-Your-Terminal_Watermarked.bcf2fe57f200.jpg 960w, /cdn-cgi/image/width=1920,format=auto/https://files.realpython.com/media/How-to-Use-Gemini-CLI-to-Work-with-LLMs-in-Your-Terminal_Watermarked.bcf2fe57f200.jpg 1920w" sizes="(min-width: 1200px) 142px, (min-width: 1000px) 122px, (min-width: 780px) 112px, (min-width: 580px) 139px, calc(100vw - 62px)">
<div class="card-img-overlay d-flex align-items-center">
<div class="mx-auto">
<span class="text-light" style="opacity: 0.90;"><span class="icon baseline scale2x" aria-hidden="true"><svg aria-hidden="true"><use href="/static/icons.5eccc70ec931.svg#@quiz"></use></svg></span></span>
</div>
</div>
</div>
</a>
</div>
<div class="col">
<div class="mt-3 d-md-none"></div>
<p class="small text-muted mb-0"><strong>Interactive Quiz</strong></p>
<a href="/quizzes/how-to-use-gemini-cli/" class="stretched-link"><span class="my-0 h4">How to Use Google's Gemini CLI for AI Code Assistance</span></a>
<p class="text-muted mb-0 small">Learn how to install, authenticate, and safely use the Gemini CLI to interact with Google's Gemini models.</p>
</div>
</div>
</div>
<h2 id="step-1-install-and-set-up-gemini-cli">Step 1: Install and Set Up Gemini CLI<a class="headerlink" href="#step-1-install-and-set-up-gemini-cli" title="Permanent link"></a></h2>
<p>Before you can start using the AI-powered features of <a href="https://geminicli.com/">Gemini CLI</a>, you need to get it installed on your system and authenticate with Google. In this step, you’ll verify your Node.js installation, install Gemini CLI globally, and complete the authentication process to access the free tier.</p>
<h3 id="verify-your-nodejs-installation">Verify Your Node.js Installation<a class="headerlink" href="#verify-your-nodejs-installation" title="Permanent link"></a></h3>
<p>Gemini CLI is primarily implemented in <a href="https://www.typescriptlang.org/">TypeScript</a>, which requires <a href="https://nodejs.org/">Node.js</a>. You’ll need Node.js version 20 or higher to run Gemini CLI. First, check if you have Node.js installed in the required version by opening your terminal and running this command:</p>
<code-block class="mb-3" aria-label="Code block" data-syntax-language="console" data-is-repl="true">
<div class="codeblock__header codeblock--yellow">
<span class="mr-2 noselect" aria-label="Language">Shell</span>
<div class="noselect">
<span class="codeblock__output-toggle" title="Toggle prompts and output" role="button"><span class="icon baseline js-codeblock-output-on codeblock__header--icon-lower" aria-hidden="true"><svg aria-hidden="true"><use href="/static/icons.5eccc70ec931.svg#regular--rectangle-terminal"></use></svg></span></span>
</div>
</div>
<div class="codeblock__contents">
<div class="highlight highlight--with-header"><pre><span></span><code><span class="gp">$ </span>node<span class="w"> </span>--version
<span class="go">v24.11.1</span>
</code></pre></div>
<button class="codeblock__copy btn btn-outline-secondary border m-1 px-1 d-hover-only" title="Copy to clipboard"><span class="icon baseline" aria-hidden="true"><svg aria-hidden="true"><use href="/static/icons.5eccc70ec931.svg#@copy"></use></svg></span></button>
</div>
</code-block>
<p>If you see a version number of 20 or higher, then you’re all set. Otherwise, if you encounter a <em>command not found</em> error or have an older version, then you’ll need to install or update Node.js before continuing.</p>
<div class="alert alert-primary" role="alert">
<p><strong>Note:</strong> If you’re on macOS or Linux, then you can leverage <a href="https://brew.sh/">Homebrew</a> to get Gemini CLI without having to install Node.js yourself.</p>
</div>
<p>The recommended approach to install Node.js is to use the <a href="https://github.com/nvm-sh/nvm">Node Version Manager (nvm)</a>, which allows you to install and switch between multiple Node.js versions, much like <a href="https://realpython.com/intro-to-pyenv/">pyenv</a> does for Python. You can find detailed installation instructions for your operating system on the <a href="https://nodejs.org/en/download">Node.js download page</a>.</p>
<p>Once Node.js is installed, you’ll also have access to the <a href="https://github.com/npm/cli">Node Package Manager (npm)</a>, which you’ll use in the next step.</p>
<h3 id="install-gemini-cli-globally">Install Gemini CLI Globally<a class="headerlink" href="#install-gemini-cli-globally" title="Permanent link"></a></h3>
<p>With Node.js installed, you can now install Gemini CLI using npm. The <code>-g</code> flag installs the package globally, making the <code>gemini</code> command available from anywhere in your file system:</p>
<code-block class="mb-3" aria-label="Code block" data-syntax-language="console" data-is-repl="true">
<div class="codeblock__header codeblock--yellow">
<span class="mr-2 noselect" aria-label="Language">Shell</span>
<div class="noselect">
<span class="codeblock__output-toggle" title="Toggle prompts and output" role="button"><span class="icon baseline js-codeblock-output-on codeblock__header--icon-lower" aria-hidden="true"><svg aria-hidden="true"><use href="/static/icons.5eccc70ec931.svg#regular--rectangle-terminal"></use></svg></span></span>
</div>
</div>
<div class="codeblock__contents">
<div class="highlight highlight--with-header"><pre><span></span><code><span class="gp">$ </span>npm<span class="w"> </span>install<span class="w"> </span>-g<span class="w"> </span>@google/gemini-cli
</code></pre></div>
<button class="codeblock__copy btn btn-outline-secondary border m-1 px-1 d-hover-only" title="Copy to clipboard"><span class="icon baseline" aria-hidden="true"><svg aria-hidden="true"><use href="/static/icons.5eccc70ec931.svg#@copy"></use></svg></span></button>
</div>
</code-block>
</div><h2><a href="https://realpython.com/how-to-use-gemini-cli/?utm_source=realpython&utm_medium=rss">Read the full article at https://realpython.com/how-to-use-gemini-cli/ »</a></h2>
<hr />
<p><em>[ Improve Your Python With 🐍 Python Tricks 💌 – Get a short & sweet Python Trick delivered to your inbox every couple of days. <a href="https://realpython.com/python-tricks/?utm_source=realpython&utm_medium=rss&utm_campaign=footer">>> Click here to learn more and see examples</a> ]</em></p>
Quiz: How to Use Google's Gemini CLI for AI Code Assistance
https://realpython.com/quizzes/how-to-use-gemini-cli/
2025-12-03T12:00:00+00:00
Learn how to install, authenticate, and safely use the Gemini CLI to interact with Google's Gemini models.
<p>In this quiz, you’ll test your understanding of the <a href="https://realpython.com/how-to-use-gemini-cli/">How to Use Google’s Gemini CLI for AI Code Assistance</a> tutorial.</p>
<p>By working through these questions, you’ll revisit how to install and verify prerequisites like Node.js, explore authentication options, and understand the CLI’s permission and safety model. You’ll also practice managing interactive sessions, enforcing stronger models, and approving or editing shell commands securely.</p>
<p>To deepen your understanding, review the sections on verifying your environment, authenticating safely, and running interactive prompts in the linked tutorial.</p>
<hr />
<p><em>[ Improve Your Python With 🐍 Python Tricks 💌 – Get a short & sweet Python Trick delivered to your inbox every couple of days. <a href="https://realpython.com/python-tricks/?utm_source=realpython&utm_medium=rss&utm_campaign=footer">>> Click here to learn more and see examples</a> ]</em></p>
Introduction to pandas
https://realpython.com/courses/introduction-pandas/
2025-12-02T14:00:00+00:00
Learn pandas DataFrames: explore, clean, and visualize data with powerful tools for analysis. Delete unneeded data, import data from a CSV file, and more.
<p>The <a href="https://pandas.pydata.org/pandas-docs/stable/reference/frame.html">pandas DataFrame</a> is a <a href="https://pandas.pydata.org/pandas-docs/stable/user_guide/dsintro.html">structure</a> that contains <strong>two-dimensional data</strong> and its corresponding <strong>labels</strong>. DataFrames are widely used in <a href="https://realpython.com/tutorials/data-science/">data science</a>, <a href="https://realpython.com/tutorials/machine-learning/">machine learning</a>, scientific computing, and many other data-intensive fields.</p>
<p>DataFrames are similar to <a href="https://realpython.com/python-sql-libraries/">SQL tables</a> or the spreadsheets that you work with in Excel or Calc. In many cases, DataFrames are faster, easier to use, and more powerful than tables or spreadsheets because they’re an integral part of the <a href="https://www.python.org/about/">Python</a> and <a href="https://numpy.org/">NumPy</a> ecosystems.</p>
<p><strong>In this video course, you’ll learn:</strong></p>
<ul>
<li>What a <strong>pandas DataFrame</strong> is and how to create one</li>
<li>How to <strong>access, modify, add, sort, filter, and delete</strong> data</li>
<li>How to handle <strong>missing values</strong></li>
<li>How to work with <strong>time-series data</strong></li>
<li>How to quickly <strong>visualize</strong> data</li>
</ul>
<hr />
<p><em>[ Improve Your Python With 🐍 Python Tricks 💌 – Get a short & sweet Python Trick delivered to your inbox every couple of days. <a href="https://realpython.com/python-tricks/?utm_source=realpython&utm_medium=rss&utm_campaign=footer">>> Click here to learn more and see examples</a> ]</em></p>
Quantum Computing Basics With Qiskit
https://realpython.com/quantum-computing-basics/
2025-12-01T14:00:00+00:00
Understand quantum computing basics like qubits, superposition, and entanglement. Then use Python Qiskit to build your first quantum circuit.
<div><p>Every classical computer reduces the world to 0s and 1s. That binary framework has carried us from calculators to supercomputers, but some problems demand checking through 2<sup><em>n</em></sup> possibilities, a task that outpaces even the best machines. Now, what if information could exist in many states at once? That <em>what if</em> turned into a new model called <strong>quantum computation</strong>. Keep reading to break with binaries and get an overview of quantum computing basics.</p>
<p><strong>By the end of this tutorial, you’ll understand that:</strong></p>
<ul>
<li><strong>Qubits</strong>, or quantum bits, are the basic units of quantum computing.</li>
<li>A qubit can be in a <strong>superposition</strong> of 0 and 1. This means its state is a precise combination of both until measurement forces it to become either 0 or 1.</li>
<li>The <strong>Bloch sphere</strong> is a standard way to visualize what a single qubit is doing.</li>
<li><strong>Entanglement</strong> creates strong correlations between two or more qubits, so measuring one tells you something about the others that you can’t explain with classical reasoning alone.</li>
<li><strong>Interference</strong> adjusts probability amplitudes so that wrong outcomes cancel and useful outcomes reinforce.</li>
<li><strong>Quantum hardware</strong> comes in different architectures, each with its own strengths and limitations.</li>
<li>With Python libraries like <strong>Qiskit</strong>, you can build and run quantum circuits directly from Python.</li>
</ul>
<p>Before you jump in, it’d be a good idea to go through the basics of <em>classical</em> computing. For example, knowing <a href="https://realpython.com/python-bitwise-operators/#binary-system-in-five-minutes">how bits work</a>, what <a href="https://realpython.com/lessons/bitwise-practice-circuit-simulation/">logic gates</a> like <code>AND</code> and <code>NOT</code> do, and how you can determine the runtime complexity of an algorithm using <a href="https://en.wikipedia.org/wiki/Big_O_notation">Big O notation</a> will help you understand the differences and advantages of quantum computing.</p>
<div class="alert alert-warning" role="alert">
<p><strong markdown>Get Your Code:</strong> <a href="https://realpython.com/bonus/quantum-computing-basics-code/" class="alert-link" data-toggle="modal" data-target="#modal-quantum-computing-basics-code" markdown>Click here to download the free sample code</a> to build a quantum circuit with Qiskit.</p>
</div>
<div class="container border rounded text-wrap-pretty my-3">
<p class="my-3"><mark class="marker-highlight"><strong><span class="icon baseline" aria-hidden="true"><svg aria-hidden="true"><use href="/static/icons.5eccc70ec931.svg#@quiz"></use></svg></span> Take the Quiz:</strong></mark> Test your knowledge with our interactive “Quantum Computing Basics With Qiskit” quiz. You’ll receive a score upon completion to help you track your learning progress:</p>
<hr>
<div class="row my-3">
<div class="col-xs-12 col-sm-4 col-md-3 align-self-center">
<a href="/quizzes/quantum-computing-basics/" tabindex="-1">
<div class="embed-responsive embed-responsive-16by9">
<img class="card-img-top m-0 p-0 embed-responsive-item rounded" style="object-fit: contain; background: #abe5b2;" alt="Quantum Computing Basics With Qiskit" src="https://files.realpython.com/media/Quantum-Computing-Basics_Watermarked.ad6227489333.jpg" width="1920" height="1080" srcset="/cdn-cgi/image/width=480,format=auto/https://files.realpython.com/media/Quantum-Computing-Basics_Watermarked.ad6227489333.jpg 480w, /cdn-cgi/image/width=640,format=auto/https://files.realpython.com/media/Quantum-Computing-Basics_Watermarked.ad6227489333.jpg 640w, /cdn-cgi/image/width=960,format=auto/https://files.realpython.com/media/Quantum-Computing-Basics_Watermarked.ad6227489333.jpg 960w, /cdn-cgi/image/width=1920,format=auto/https://files.realpython.com/media/Quantum-Computing-Basics_Watermarked.ad6227489333.jpg 1920w" sizes="(min-width: 1200px) 142px, (min-width: 1000px) 122px, (min-width: 780px) 112px, (min-width: 580px) 139px, calc(100vw - 62px)">
<div class="card-img-overlay d-flex align-items-center">
<div class="mx-auto">
<span class="text-light" style="opacity: 0.90;"><span class="icon baseline scale2x" aria-hidden="true"><svg aria-hidden="true"><use href="/static/icons.5eccc70ec931.svg#@quiz"></use></svg></span></span>
</div>
</div>
</div>
</a>
</div>
<div class="col">
<div class="mt-3 d-md-none"></div>
<p class="small text-muted mb-0"><strong>Interactive Quiz</strong></p>
<a href="/quizzes/quantum-computing-basics/" class="stretched-link"><span class="my-0 h4">Quantum Computing Basics With Qiskit</span></a>
<p class="text-muted mb-0 small">Test your understanding of quantum computing basics, including superposition, qubits, entanglement, and key programming concepts.</p>
</div>
</div>
</div>
<h2 id="introduction-to-quantum-computing">Introduction to Quantum Computing<a class="headerlink" href="#introduction-to-quantum-computing" title="Permanent link"></a></h2>
<p>Quantum computing is the use of fundamental ideas from <a href="https://en.wikipedia.org/wiki/Quantum_mechanics">quantum mechanics</a> to perform computations on special devices called quantum computers. Quantum systems can process information in ways that classical computers can’t. For example, they can explore multiple possibilities at once. This capability is thanks to concepts like <strong>superposition</strong>, <strong>entanglement</strong>, and <strong>interference</strong>, which you’ll explore soon.</p>
<p>To see how quantum computing works, it helps to look at the main quantum concepts in the context of computing and consider how they differ from classical approaches. You’ll cover these essential concepts in this tutorial.</p>
<p>Before moving on, keep in mind that quantum mechanics and quantum computing are often counterintuitive because they occur only at very small scales and not in everyday life. Even <a href="https://en.wikipedia.org/wiki/Niels_Bohr">Niels Bohr</a>, one of the founders of quantum theory, once said:</p>
<blockquote>
<p>If quantum mechanics hasn’t profoundly shocked you, you haven’t understood it yet. (<a href="https://www.nielsbohr.net/p/quotes.html">Source</a>)</p>
<p>— Niels Bohr</p>
</blockquote>
<p>Until recently, quantum computing was seen almost entirely as a physics domain, which kept people in other fields from applying it to their own work. The good news is that you don’t need to fully grasp the physics to understand how quantum computers can solve some problems more efficiently than classical ones. You can focus on the concepts and their implementation, and only later dive into the math if you want a deeper understanding.</p>
<p>To start, you’ll look at the basic unit of quantum information—<strong>quantum bits</strong>, or <strong>qubits</strong>—and learn how they differ from classical bits.</p>
<h2 id="qubits-superposition-and-measurement">Qubits, Superposition, and Measurement<a class="headerlink" href="#qubits-superposition-and-measurement" title="Permanent link"></a></h2>
<p><a href="https://en.wikipedia.org/wiki/Qubit">Qubits</a>, or quantum bits, are the fundamental units of quantum information. A classical bit can only be 0 or 1, but a qubit can exist in a linear combination of both states at once, a property called superposition. Physically, this usually means that the qubit is a two-level system, such as two energy levels of an atom, that can exist in a superposition of those levels.</p>
<p><a href="https://en.wikipedia.org/wiki/Quantum_superposition">Superposition</a> allows qubits to represent multiple possibilities at the same time, allowing quantum computing programs to explore many solutions in parallel.</p>
<p>To understand superposition, think of flipping a coin. A classical coin lands as either heads or tails. A quantum coin, however, can exist in a state that’s a blend of both heads and tails simultaneously. This is what physicists mean when they say a qubit exists in a linear combination of 0 and 1.</p>
<p>The key difference is that while the coin is spinning in the air, you know it’ll eventually be one or zero, whereas a qubit in superposition has no definite value until it is measured. </p>
<p>A qubit remains in superposition until you look at it, or more formally, <em>measure</em> it. <a href="https://en.wikipedia.org/wiki/Measurement_in_quantum_mechanics">Measurement</a> forces the qubit to collapse into one of its basis states, 0 or 1, just like your usual classical bits. The outcome is probabilistic: You can’t know in advance which result you’ll get, but you can calculate the chances based on the qubit’s state beforehand. </p>
<div class="alert alert-primary" role="alert">
<p><strong>Note:</strong> Looking at a superposition state actually destroys the superposition and collapses the qubit into a 0 or 1, or in other words, destroys the “quantumness” of the state. This means you can’t visualize qubits like bits. Instead, you view qubits as a mathematical object. However, they can be built from various physical systems: the spin of an electron, the polarization of a photon, or the energy levels of an atom.</p>
</div>
<p>Visualizing qubits and superposition is tricky and needs some extra mathematical tools. Turns out, a coin that’s free to rotate in three dimensions is a good analogy for one way of visualizing the quantum state of a qubit, called the <strong>Bloch Sphere</strong>.</p>
<p>The <a href="https://en.wikipedia.org/wiki/Bloch_sphere"><strong>Bloch sphere</strong></a> is a geometrical, 3D sphere that’s often used to visualize qubits and their superpositions. The states of the qubits, including superpositions, are represented as points on the surface of a sphere. The closer the point is to the north pole, the higher the chance of measuring 0, and vice versa for 1:</p>
<figure class="js-lightbox"><a href="https://files.realpython.com/media/bloch-sphere-unit-vectors.3f946dd8f01f.png" target="_blank"><img loading="lazy" class="img-fluid mx-auto d-block " src="https://files.realpython.com/media/bloch-sphere-unit-vectors.3f946dd8f01f.png" width="813" height="422" srcset="/cdn-cgi/image/width=203,format=auto/https://files.realpython.com/media/bloch-sphere-unit-vectors.3f946dd8f01f.png 203w, /cdn-cgi/image/width=271,format=auto/https://files.realpython.com/media/bloch-sphere-unit-vectors.3f946dd8f01f.png 271w, /cdn-cgi/image/width=406,format=auto/https://files.realpython.com/media/bloch-sphere-unit-vectors.3f946dd8f01f.png 406w, /cdn-cgi/image/width=813,format=auto/https://files.realpython.com/media/bloch-sphere-unit-vectors.3f946dd8f01f.png 813w" sizes="(min-width: 1200px) 690px, (min-width: 780px) calc(-5vw + 669px), (min-width: 580px) 510px, calc(100vw - 30px)" alt="A Bloch sphere showing a qubit in the states 0 and 1." data-asset="6590"></a><figcaption class="figure-caption text-center">Two Bloch spheres showing a qubit in the 0 (left) state and a qubit in the 1 state (right)</figcaption></figure>
<p>For example, the north pole represents the state 0, and the south pole represents 1. What’s interesting about this sphere is that you can visualize superposition states as well:</p>
<figure class="js-lightbox"><a href="https://files.realpython.com/media/bloch-sphere-superposition.238b06594dd2.png" target="_blank"><img loading="lazy" class="img-fluid mx-auto d-block " src="https://files.realpython.com/media/bloch-sphere-superposition.238b06594dd2.png" width="436" height="453" srcset="/cdn-cgi/image/width=109,format=auto/https://files.realpython.com/media/bloch-sphere-superposition.238b06594dd2.png 109w, /cdn-cgi/image/width=145,format=auto/https://files.realpython.com/media/bloch-sphere-superposition.238b06594dd2.png 145w, /cdn-cgi/image/width=218,format=auto/https://files.realpython.com/media/bloch-sphere-superposition.238b06594dd2.png 218w, /cdn-cgi/image/width=436,format=auto/https://files.realpython.com/media/bloch-sphere-superposition.238b06594dd2.png 436w" sizes="(min-width: 1200px) 690px, (min-width: 780px) calc(-5vw + 669px), (min-width: 580px) 510px, calc(100vw - 30px)" alt="A Bloch sphere showing a qubit in a superposition state." data-asset="6591"></a><figcaption class="figure-caption text-center">A Bloch sphere showing a qubit in a superposition state.</figcaption></figure>
</div><h2><a href="https://realpython.com/quantum-computing-basics/?utm_source=realpython&utm_medium=rss">Read the full article at https://realpython.com/quantum-computing-basics/ »</a></h2>
<hr />
<p><em>[ Improve Your Python With 🐍 Python Tricks 💌 – Get a short & sweet Python Trick delivered to your inbox every couple of days. <a href="https://realpython.com/python-tricks/?utm_source=realpython&utm_medium=rss&utm_campaign=footer">>> Click here to learn more and see examples</a> ]</em></p>
Quiz: Quantum Computing Basics With Qiskit
https://realpython.com/quizzes/quantum-computing-basics/
2025-12-01T12:00:00+00:00
Test your understanding of quantum computing basics, including superposition, qubits, entanglement, and key programming concepts.
<p>Dive into quantum computing fundamentals with this quiz. You’ll practice key ideas like superposition, measurement, entanglement, and how quantum and classical systems work together. You’ll also revisit essential Qiskit commands and understand what limits today’s quantum computers.</p>
<p>Need a refresher? Check out <a href="https://realpython.com/quantum-computing-basics/">Quantum Computing Basics With Qiskit</a> for clear explanations and hands-on examples.</p>
<hr />
<p><em>[ Improve Your Python With 🐍 Python Tricks 💌 – Get a short & sweet Python Trick delivered to your inbox every couple of days. <a href="https://realpython.com/python-tricks/?utm_source=realpython&utm_medium=rss&utm_campaign=footer">>> Click here to learn more and see examples</a> ]</em></p>
How to Convert Bytes to Strings in Python
https://realpython.com/convert-python-bytes-to-strings/
2025-11-26T14:00:00+00:00
Turn Python bytes to strings, pick the right encoding, and validate results with clear error handling strategies.
<div><p>Converting bytes into readable strings in Python is an effective way to work with raw bytes fetched from files, databases, or APIs. You can do this in just three steps using the <code>bytes.decode()</code> method. This guide lets you convert byte data into clean text, giving you a result similar to what’s shown in the following example:</p>
<code-block class="mb-3" aria-label="Code block" data-syntax-language="pycon" data-is-repl="true">
<div class="codeblock__header codeblock--blue">
<span class="mr-2 noselect" aria-label="Language">Python</span>
<div class="noselect">
<span class="codeblock__output-toggle" title="Toggle prompts and output" role="button"><span class="icon baseline js-codeblock-output-on codeblock__header--icon-lower" aria-hidden="true"><svg aria-hidden="true"><use href="/static/icons.5eccc70ec931.svg#regular--rectangle-terminal"></use></svg></span></span>
</div>
</div>
<div class="codeblock__contents">
<div class="highlight highlight--with-header"><pre><span></span><code><span class="gp">>>> </span><span class="n">binary_data</span> <span class="o">=</span> <span class="nb">bytes</span><span class="p">([</span><span class="mi">100</span><span class="p">,</span> <span class="mi">195</span><span class="p">,</span> <span class="mi">169</span><span class="p">,</span> <span class="mi">106</span><span class="p">,</span> <span class="mi">195</span><span class="p">,</span> <span class="mi">160</span><span class="p">,</span> <span class="mi">32</span><span class="p">,</span> <span class="mi">118</span><span class="p">,</span> <span class="mi">117</span><span class="p">])</span>
<span class="gp">>>> </span><span class="n">binary_data</span><span class="o">.</span><span class="n">decode</span><span class="p">(</span><span class="n">encoding</span><span class="o">=</span><span class="s2">"utf-8"</span><span class="p">)</span>
<span class="go">'déjà vu'</span>
</code></pre></div>
<button class="codeblock__copy btn btn-outline-secondary border m-1 px-1 d-hover-only" title="Copy to clipboard"><span class="icon baseline" aria-hidden="true"><svg aria-hidden="true"><use href="/static/icons.5eccc70ec931.svg#@copy"></use></svg></span></button>
</div>
</code-block>
<p>By interpreting the bytes according to a specific <a href="https://realpython.com/python-encodings-guide/">character encoding</a>, Python transforms numeric byte values into their corresponding characters. This allows you to seamlessly handle data loaded from files, network responses, or other binary sources and work with it as normal text.</p>
<p>A <a href="https://en.wikipedia.org/wiki/Byte">byte</a> is a fundamental unit of digital storage and processing. Composed of eight bits (binary digits), it’s a basic building block of data in computing. Bytes represent a vast range of data types and are used extensively in data storage and in networking. It’s important to be able to manage and handle bytes where they come up. Sometimes they need to be converted into strings for further use or comprehensibility.</p>
<p>By the end of this guide, you’ll be able to convert <a href="https://realpython.com/python-bytes/">Python <code>bytes</code></a> to strings so that you can work with byte data in a human-readable format.</p>
<div class="alert alert-warning" role="alert">
<p><strong markdown>Get Your Code:</strong> <a href="https://realpython.com/bonus/convert-python-bytes-to-strings-code/" class="alert-link" data-toggle="modal" data-target="#modal-convert-python-bytes-to-strings-code" markdown>Click here to download the free sample code</a> that you’ll use to convert bytes to strings in Python.</p>
</div>
<h2 id="step-1-obtain-the-byte-data">Step 1: Obtain the Byte Data<a class="headerlink" href="#step-1-obtain-the-byte-data" title="Permanent link"></a></h2>
<p>Before converting <code>bytes</code> to <a href="https://realpython.com/python-strings/">strings</a>, you’ll need some actual bytes to work with. In everyday programming, you may not have to deal with bytes directly at all, as Python often handles their encoding and decoding behind the scenes.</p>
<p>Binary data exchanged over the internet can be expressed in different formats, such as raw binary streams, <a href="https://en.wikipedia.org/wiki/Base64">Base64</a>, or <a href="https://en.wikipedia.org/wiki/Hexadecimal">hexadecimal</a> strings. When you browse a web page, download a file, or chat with a colleague, the data that emerges travels as numeric bytes before it is interpreted as text that you can read.</p>
<p>In this step, however, you’ll obtain byte data using one of two approaches:</p>
<ul>
<li>Using the <a href="https://realpython.com/python-bytes/#the-bytes-literal-format"><code>bytes</code> literal</a> (<code>b""</code>)</li>
<li>Using the <a href="/ref/stdlib/urllib/" class="ref-link"><code>urllib</code></a> package</li>
</ul>
<p>You’ll soon find that using the <code>urllib</code> package requires that you go online. You can, however, create <code>bytes</code> manually without reaching out to the internet at all. You do this by prefixing a string with <code>b</code>, which creates a <a href="/ref/builtin-types/bytes/" class="ref-link"><code>bytes</code></a> literal containing the text inside:</p>
<code-block class="mb-3" aria-label="Code block" data-syntax-language="python">
<div class="codeblock__header codeblock--blue">
<span class="mr-2 noselect" aria-label="Language">Python</span>
<div class="noselect">
</div>
</div>
<div class="codeblock__contents">
<div class="highlight highlight--with-header"><pre><span></span><code><span class="n">raw_bytes</span> <span class="o">=</span> <span class="sa">b</span><span class="s2">"These are some interesting bytes"</span>
</code></pre></div>
<button class="codeblock__copy btn btn-outline-secondary border m-1 px-1 d-hover-only" title="Copy to clipboard"><span class="icon baseline" aria-hidden="true"><svg aria-hidden="true"><use href="/static/icons.5eccc70ec931.svg#@copy"></use></svg></span></button>
</div>
</code-block>
<p>You may be wondering why you have to create a <code>bytes</code> object at all from strings that you can read. This isn’t just a convenience. While <code>bytes</code> and strings share most of their methods, you can’t mix them freely. If you pass string arguments to a <code>bytes</code> method, then you’ll get an error:</p>
<code-block class="mb-3" aria-label="Code block" data-syntax-language="pycon" data-is-repl="true">
<div class="codeblock__header codeblock--blue">
<span class="mr-2 noselect" aria-label="Language">Python</span>
<div class="noselect">
<span class="codeblock__output-toggle" title="Toggle prompts and output" role="button"><span class="icon baseline js-codeblock-output-on codeblock__header--icon-lower" aria-hidden="true"><svg aria-hidden="true"><use href="/static/icons.5eccc70ec931.svg#regular--rectangle-terminal"></use></svg></span></span>
</div>
</div>
<div class="codeblock__contents">
<div class="highlight highlight--with-header"><pre><span></span><code><span class="gp">>>> </span><span class="n">raw_bytes</span> <span class="o">=</span> <span class="sa">b</span><span class="s2">"These are some interesting bytes"</span>
<span class="gp">>>> </span><span class="n">raw_bytes</span><span class="o">.</span><span class="n">replace</span><span class="p">(</span><span class="s2">"y"</span><span class="p">,</span> <span class="s2">"o"</span><span class="p">)</span>
<span class="gt">Traceback (most recent call last):</span>
<span class="w"> </span><span class="c">...</span>
<span class="gr">TypeError</span>: <span class="n">a bytes-like object is required, not 'str'</span>
</code></pre></div>
<button class="codeblock__copy btn btn-outline-secondary border m-1 px-1 d-hover-only" title="Copy to clipboard"><span class="icon baseline" aria-hidden="true"><svg aria-hidden="true"><use href="/static/icons.5eccc70ec931.svg#@copy"></use></svg></span></button>
</div>
</code-block>
<p>A <code>bytes</code> object only accepts other <a href="/ref/glossary/bytes-like-object/" class="ref-link">bytes-like objects</a> as arguments. If you try to use a string like <code>"y"</code> with a <code>bytes</code> method, then Python raises a <a href="/ref/builtin-exceptions/typeerror/" class="ref-link"><code>TypeError</code></a>. To work with raw binary data, you must explicitly use <code>bytes</code>, not strings.</p>
<p>Note that you can represent the same information using alternative <a href="https://en.wikipedia.org/wiki/Computer_number_format">numeral formats</a>, including binary, decimal, or hexadecimal. For instance, in the following code snippet, you convert the same <code>bytes</code> object from the above code example into hexadecimal and decimal formats: </p>
</div><h2><a href="https://realpython.com/convert-python-bytes-to-strings/?utm_source=realpython&utm_medium=rss">Read the full article at https://realpython.com/convert-python-bytes-to-strings/ »</a></h2>
<hr />
<p><em>[ Improve Your Python With 🐍 Python Tricks 💌 – Get a short & sweet Python Trick delivered to your inbox every couple of days. <a href="https://realpython.com/python-tricks/?utm_source=realpython&utm_medium=rss&utm_campaign=footer">>> Click here to learn more and see examples</a> ]</em></p>
Getting Started With Claude Code
https://realpython.com/courses/getting-started-claude-code/
2025-11-25T14:00:00+00:00
Learn to set up and use Claude Code for Python projects: install, run commands, and integrate with Git.
<p>Learn how to set up and start using Claude Code to boost your Python workflow. Learn how it differs from Claude Chat and how to use it effectively in your development setup.</p>
<p><strong>You’ll learn how to:</strong></p>
<ul>
<li>Install and configure Claude Code</li>
<li>Run it safely inside project directories</li>
<li>Work with CLAUDE.md for task context</li>
<li>Use Git integration for smoother coding workflows</li>
<li>Apply Claude Code to automate real programming tasks</li>
</ul>
<hr />
<p><em>[ Improve Your Python With 🐍 Python Tricks 💌 – Get a short & sweet Python Trick delivered to your inbox every couple of days. <a href="https://realpython.com/python-tricks/?utm_source=realpython&utm_medium=rss&utm_campaign=footer">>> Click here to learn more and see examples</a> ]</em></p>
How to Properly Indent Python Code
https://realpython.com/how-to-indent-in-python/
2025-11-24T14:00:00+00:00
Learn how to properly indent Python code in IDEs, Python-aware editors, and plain text editors—plus explore PEP 8 formatters like Black and Ruff.
<div><p>Knowing how to properly indent Python code is a key skill for becoming an accomplished Python developer. Beginning Python programmers know that indentation is required, but learning to indent code so it’s readable, syntactically correct, and easy to maintain is a skill that takes practice.</p>
<p><strong>By the end of this tutorial, you’ll know:</strong></p>
<ul>
<li>How to <strong>properly indent Python code</strong> in a variety of editors</li>
<li>How <strong>your choice of editor</strong> can impact your Python code</li>
<li>How to <strong>indent code using spaces</strong> in simple text editors</li>
<li>How to use <strong>code formatters</strong> to properly indent Python code automatically</li>
<li>Why <strong>indentation is required</strong> when writing Python code</li>
</ul>
<p>With this knowledge, you’ll be able to write Python code confidently in any environment.</p>
<div class="alert alert-warning" role="alert">
<p><strong markdown>Get Your Code:</strong> <a href="https://realpython.com/bonus/how-to-indent-in-python-code/" class="alert-link" data-toggle="modal" data-target="#modal-how-to-indent-in-python-code" markdown>Click here to download the free sample code</a> you’ll use to learn how to properly indent Python code.</p>
</div>
<h2 id="how-to-indent-code-in-python">How to Indent Code in Python<a class="headerlink" href="#how-to-indent-code-in-python" title="Permanent link"></a></h2>
<p><a href="/ref/glossary/indentation/" class="ref-link">Indenting</a> your code means adding spaces to the beginning of a line, which shifts the start of the line to the right, as shown below:</p>
<code-block class="mb-3" aria-label="Code block" data-syntax-language="python">
<div class="codeblock__header codeblock--blue">
<span class="mr-2 noselect" aria-label="Language">Python</span>
<div class="noselect">
</div>
</div>
<div class="codeblock__contents">
<div class="highlight highlight--with-header"><pre><span></span><code><span class="n">number</span> <span class="o">=</span> <span class="mi">7</span>
<span class="k">if</span> <span class="n">number</span> <span class="o">></span> <span class="mi">0</span><span class="p">:</span>
<span class="hll"> <span class="nb">print</span><span class="p">(</span><span class="s2">"It's a positive number"</span><span class="p">)</span>
</span></code></pre></div>
<button class="codeblock__copy btn btn-outline-secondary border m-1 px-1 d-hover-only" title="Copy to clipboard"><span class="icon baseline" aria-hidden="true"><svg aria-hidden="true"><use href="/static/icons.5eccc70ec931.svg#@copy"></use></svg></span></button>
</div>
</code-block>
<p>In this example, the first two lines aren’t indented, while the third line is indented.</p>
<p>How you indent your Python code depends on your coding environment. Most editors and <a href="/ref/glossary/ide/" class="ref-link">integrated development environments (IDEs)</a> can indent Python code correctly with little to no input from the user. You’ll see examples of this in the sections that follow.</p>
<h3 id="python-aware-editors">Python-Aware Editors<a class="headerlink" href="#python-aware-editors" title="Permanent link"></a></h3>
<p>In most cases, you’ll be working in a Python-aware environment. This might be a full Python IDE such as <a href="https://realpython.com/pycharm-guide/">PyCharm</a>, a code editor like <a href="https://realpython.com/python-development-visual-studio-code/">Visual Studio Code</a>, the <a href="https://realpython.com/python-repl/">Python REPL</a>, <a href="https://realpython.com/ipython-interactive-python-shell/">IPython</a>, <a href="https://realpython.com/python-idle/">IDLE</a>, or even a <a href="https://realpython.com/jupyter-notebook-introduction/">Jupyter</a> notebook. All these environments understand Python syntax and indent your code properly as you type.</p>
<div class="alert alert-primary" role="alert">
<p><strong>Note:</strong> <a href="https://peps.python.org/pep-0008/">PEP 8</a> is the style guide for Python that was first introduced in 2001. Among other recommendations, it specifies that code indentation should be <a href="https://peps.python.org/pep-0008/#indentation">four spaces per indentation level</a>. All environments discussed here follow that standard.</p>
</div>
<p>Here’s a small example to show this automatic indentation. You’ll use the following code to see how each environment automatically indents as you type:</p>
<code-block class="mb-3" aria-label="Code block" data-syntax-language="python">
<div class="codeblock__header codeblock--blue">
<span class="mr-2 noselect" aria-label="Language">Python</span>
<span class="mr-2" aria-label="Filename"><code style="color: inherit; background: inherit;">lucky_number.py</code></span>
<div class="noselect">
</div>
</div>
<div class="codeblock__contents">
<div class="highlight highlight--with-header"><pre><span></span><code><span class="linenos"> 1</span><span class="n">lucky_number</span> <span class="o">=</span> <span class="mi">7</span>
<span class="linenos"> 2</span><span class="k">for</span> <span class="n">number</span> <span class="ow">in</span> <span class="nb">range</span><span class="p">(</span><span class="mi">10</span><span class="p">):</span>
<span class="linenos"> 3</span> <span class="k">if</span> <span class="n">number</span> <span class="o">==</span> <span class="n">lucky_number</span><span class="p">:</span>
<span class="linenos"> 4</span> <span class="nb">print</span><span class="p">(</span><span class="s2">"Found the lucky number!"</span><span class="p">)</span>
<span class="linenos"> 5</span> <span class="k">else</span><span class="p">:</span>
<span class="linenos"> 6</span> <span class="nb">print</span><span class="p">(</span><span class="sa">f</span><span class="s2">"</span><span class="si">{</span><span class="n">number</span><span class="si">}</span><span class="s2"> is not my lucky number."</span><span class="p">)</span>
<span class="linenos"> 7</span>
<span class="linenos"> 8</span><span class="nb">print</span><span class="p">(</span><span class="s2">"Done."</span><span class="p">)</span>
</code></pre></div>
<button class="codeblock__copy btn btn-outline-secondary border m-1 px-1 d-hover-only" title="Copy to clipboard"><span class="icon baseline" aria-hidden="true"><svg aria-hidden="true"><use href="/static/icons.5eccc70ec931.svg#@copy"></use></svg></span></button>
</div>
</code-block>
<p>This example shows how indenting happens automatically and how to <strong>de-indent</strong> a line of code. De-indenting—also called <strong>dedenting</strong>—means removing spaces at the beginning of a line, which moves the start of the line to the left. The code on <strong>lines 5 and 8</strong> needs to be de-indented relative to the previous lines to close the preceding <a href="https://en.wikipedia.org/wiki/Block_(programming)">code blocks</a>. For a detailed explanation of the indentation in this code, expand the collapsible section below. </p>
<div class="card mb-3" id="collapse_card9fbee3">
<div class="card-header border-0">
<p class="m-0">
<button class="btn w-100" data-toggle="collapse" data-target="#collapse9fbee3" aria-expanded="false" aria-controls="collapse9fbee3" markdown="1"><span class="float-left" markdown="1">Code Explanation</span><span class="float-right text-muted">Show/Hide</span></button>
</p>
</div>
<div class="collapse js-collapsible-section" data-parent="#collapse_card9fbee3" id="collapse9fbee3">
<div class="card-body">
<p>The code above shows different levels of indentation, combining a <code>for</code> loop with an <code>if</code> statement:</p>
<ul>
<li><strong>Line 1</strong> initializes the variable <code>lucky_number</code> to the integer value of <code>7</code>.</li>
<li><strong>Line 2</strong> starts a <code>for</code> loop using <code>number</code> as an iterator over a range of values from <code>0</code> to <code>9</code>.</li>
<li><strong>Line 3</strong> checks if <code>number</code> is equal to <code>lucky_number</code>. This line is indented to show it’s part of the <code>for</code> loop’s body.</li>
<li><strong>Line 4</strong> prints a message when the condition <code>number == lucky_number</code> is <code>True</code>. This line is indented to show it’s part of the body of the <code>if</code> statement.</li>
<li><strong>Line 5</strong> provides a way to act when the condition on <strong>line 3</strong> is <code>False</code>. This line is de-indented to show it’s part of the <code>if</code> statement on <strong>line 3</strong>.</li>
<li><strong>Line 6</strong> prints a message when the condition <code>number == lucky_number</code> is <code>False</code>. This line is indented to show it’s part of the body of the <code>else</code> clause.</li>
<li><strong>Line 8</strong> prints a final message. It’s de-indented to show it’s not part of the <code>for</code> loop, but executes after the <code>for</code> loop is done.</li>
</ul>
<p>If any part of this code is unfamiliar to you, you can learn more by exploring these resources:</p>
<ul>
<li>For more on <code>for</code> loops, read <a href="https://realpython.com/python-for-loop/">Python <code>for</code> Loops: The Pythonic Way</a>.</li>
<li>For more on <code>range()</code>, read <a href="https://realpython.com/python-range/">Python <code>range()</code>: Represent Numerical Ranges</a>.</li>
<li>For more on <code>if</code> and <code>else</code> clauses, read <a href="https://realpython.com/python-conditional-statements/">Conditional Statements in Python</a>.</li>
<li>For more on the <code>print()</code> function, read <a href="https://realpython.com/python-print/">Your Guide to the Python <code>print()</code> Function</a>.</li>
<li>For more on f-string formatting, read <a href="https://realpython.com/python-f-strings/">Python’s F-String for String Interpolation and Formatting</a>.</li>
</ul>
</div>
</div>
</div>
<p>Each line of the code above exists at a specific <a href="https://docs.python.org/3/reference/lexical_analysis.html#indentation">indentation level</a>. All consecutive statements at the same indentation level are considered to be part of the same group or code block. The table below shows each line of code from the example, its indentation level, and what action is needed to achieve that level:</p>
<div class="table-responsive">
<table class="table table-hover">
<thead>
<tr>
<th>Code</th>
<th>Indentation Level</th>
<th>Action</th>
</tr>
</thead>
<tbody>
<tr>
<td><code>lucky_number = 7</code></td>
<td>0</td>
<td>-</td>
</tr>
<tr>
<td><code>for number in range(10):</code></td>
<td>0</td>
<td>-</td>
</tr>
<tr>
<td><code>if number == lucky_number:</code></td>
<td>1</td>
<td>Indent</td>
</tr>
<tr>
<td><code>print("Found the lucky number!")</code></td>
<td>2</td>
<td>Indent</td>
</tr>
<tr>
<td><code>else:</code></td>
<td>1</td>
<td>De-indent</td>
</tr>
<tr>
<td><code>print(f"{number} is not my lucky number.")</code></td>
<td>2</td>
<td>Indent</td>
</tr>
<tr>
<td><code>print("Done.")</code></td>
<td>0</td>
<td>De-indent</td>
</tr>
</tbody>
</table>
</div>
<p>First, here’s what it looks like to enter this code in PyCharm, a full-featured Python IDE:</p>
<figure>
<div class="embed-responsive embed-responsive-16by9 rounded mb-3 border">
<iframe loading="lazy" class="embed-responsive-item" src="https://player.vimeo.com/video/1134701175?background=1" frameborder="0" allow="fullscreen" allowfullscreen></iframe>
</div>
</figure>
<p>Notice that as you hit <span class="keys"><kbd class="key-enter">Enter</kbd></span> on <strong>line 2</strong>, PyCharm immediately indents <strong>line 3</strong> for you. The same thing happens on <strong>line 4</strong>. However, to de-indent <strong>line 5</strong> and <strong>line 8</strong>, you have to either press <span class="keys"><kbd class="key-backspace">Backspace</kbd></span> or <span class="keys"><kbd class="key-shift">Shift</kbd><span>+</span><kbd class="key-tab">Tab</kbd></span> to move the cursor back to the proper position for the next line.</p>
</div><h2><a href="https://realpython.com/how-to-indent-in-python/?utm_source=realpython&utm_medium=rss">Read the full article at https://realpython.com/how-to-indent-in-python/ »</a></h2>
<hr />
<p><em>[ Improve Your Python With 🐍 Python Tricks 💌 – Get a short & sweet Python Trick delivered to your inbox every couple of days. <a href="https://realpython.com/python-tricks/?utm_source=realpython&utm_medium=rss&utm_campaign=footer">>> Click here to learn more and see examples</a> ]</em></p>
The Real Python Podcast – Episode #275: Building a FastAPI Application & Exploring Python Concurrency
https://realpython.com/podcasts/rpp/275/
2025-11-21T12:00:00+00:00
What are the steps to get started building a FastAPI application? What are the different types of concurrency available in Python? Christopher Trudeau is back on the show this week, bringing another batch of PyCoder's Weekly articles and projects.
<p>What are the steps to get started building a FastAPI application? What are the different types of concurrency available in Python? Christopher Trudeau is back on the show this week, bringing another batch of PyCoder's Weekly articles and projects.</p>
<hr />
<p><em>[ Improve Your Python With 🐍 Python Tricks 💌 – Get a short & sweet Python Trick delivered to your inbox every couple of days. <a href="https://realpython.com/python-tricks/?utm_source=realpython&utm_medium=rss&utm_campaign=footer">>> Click here to learn more and see examples</a> ]</em></p>
Quiz: Build a Python MCP Client to Test Servers From Your Terminal
https://realpython.com/quizzes/python-mcp-client/
2025-11-19T12:00:00+00:00
Learn how to create a Python MCP client, start an AI-powered chat session, and run it from the command line. Check your understanding.
<p>In this quiz, you’ll test your understanding of how to <a href="https://realpython.com/python-mcp-client/">Build a Python MCP Client to Test Servers From Your Terminal</a>.</p>
<p>By working through this quiz, you’ll revisit how to add a minimal chat interface, create an AI handler to power the chat, handle runtime errors, and update the entry point to run the chat from the command line.</p>
<p>You will confirm when to initialize the AI handler and how to surface clear error messages to users. For a guided review, see the linked tutorial.</p>
<hr />
<p><em>[ Improve Your Python With 🐍 Python Tricks 💌 – Get a short & sweet Python Trick delivered to your inbox every couple of days. <a href="https://realpython.com/python-tricks/?utm_source=realpython&utm_medium=rss&utm_campaign=footer">>> Click here to learn more and see examples</a> ]</em></p>
Break Out of Loops With Python's break Keyword
https://realpython.com/courses/break-out-of-loops-break-keyword/
2025-11-18T14:00:00+00:00
Learn how Python’s break lets you exit for and while loops early, with practical demos from simple games to everyday data tasks.
<p>In Python, the <a href="/ref/keywords/break/" class="ref-link"><code>break</code> statement</a> lets you exit a loop prematurely, transferring control to the code that follows the loop. This tutorial guides you through using <code>break</code> in both <code>for</code> and <code>while</code> loops. You’ll also briefly explore the <code>continue</code> keyword, which complements <code>break</code> by skipping the current loop iteration.</p>
<p><strong>By the end of this video course, you’ll understand that:</strong></p>
<ul>
<li><strong>A <code>break</code> in Python</strong> is a keyword that lets you exit a loop immediately, stopping further iterations.</li>
<li><strong>Using <code>break</code> outside of loops</strong> doesn’t make sense because it’s specifically designed to exit loops early.</li>
<li><strong>The <code>break</code> doesn’t exit all loops</strong>, only the innermost loop that contains it.</li>
</ul>
<hr />
<p><em>[ Improve Your Python With 🐍 Python Tricks 💌 – Get a short & sweet Python Trick delivered to your inbox every couple of days. <a href="https://realpython.com/python-tricks/?utm_source=realpython&utm_medium=rss&utm_campaign=footer">>> Click here to learn more and see examples</a> ]</em></p>
Quiz: How to Serve a Website With FastAPI Using HTML and Jinja2
https://realpython.com/quizzes/fastapi-jinja2-template/
2025-11-17T12:00:00+00:00
Review how to build dynamic websites with FastAPI and Jinja2, and serve HTML, CSS, and JS with HTMLResponse and StaticFiles.
<p>In this quiz, you’ll test your understanding of building dynamic websites with <a href="https://realpython.com/fastapi-jinja2-template/">FastAPI and Jinja2 Templates</a>.</p>
<p>By working through this quiz, you’ll revisit how to return HTML with <code>HTMLResponse</code>, serve assets with <code>StaticFiles</code>, render Jinja2 templates with context, and include CSS and JavaScript for interactivity like copying hex color codes.</p>
<p>If you are new to FastAPI, review <a href="https://realpython.com/get-started-with-fastapi/">Get Started With FastAPI</a>. You can also brush up on <a href="https://realpython.com/defining-your-own-python-function/">Python functions</a> and <a href="https://realpython.com/html-css-python/">HTML and CSS</a>.</p>
<hr />
<p><em>[ Improve Your Python With 🐍 Python Tricks 💌 – Get a short & sweet Python Trick delivered to your inbox every couple of days. <a href="https://realpython.com/python-tricks/?utm_source=realpython&utm_medium=rss&utm_campaign=footer">>> Click here to learn more and see examples</a> ]</em></p>
The Real Python Podcast – Episode #274: Preparing Data Science Projects for Production
https://realpython.com/podcasts/rpp/274/
2025-11-14T12:00:00+00:00
How do you prepare your Python data science projects for production? What are the essential tools and techniques to make your code reproducible, organized, and testable? This week on the show, Khuyen Tran from CodeCut discusses her new book, "Production Ready Data Science."
<p>How do you prepare your Python data science projects for production? What are the essential tools and techniques to make your code reproducible, organized, and testable? This week on the show, Khuyen Tran from CodeCut discusses her new book, "Production Ready Data Science."</p>
<hr />
<p><em>[ Improve Your Python With 🐍 Python Tricks 💌 – Get a short & sweet Python Trick delivered to your inbox every couple of days. <a href="https://realpython.com/python-tricks/?utm_source=realpython&utm_medium=rss&utm_campaign=footer">>> Click here to learn more and see examples</a> ]</em></p>
Python Operators and Expressions
https://realpython.com/courses/python-operators-expressions/
2025-11-11T14:00:00+00:00
Operators let you combine objects to create expressions that perform computations -- the core of how Python works.
<p>Python operators enable you to perform computations by combining objects and operators into expressions. Understanding Python operators is essential for manipulating data effectively.</p>
<p>This video course covers arithmetic, comparison, Boolean, identity, membership, bitwise, concatenation, and repetition operators, along with augmented assignment operators. You’ll also learn how to build expressions using these operators and explore operator precedence to understand the order of operations in complex expressions.</p>
<p><strong>By the end of this video course, you’ll understand that:</strong></p>
<ul>
<li><strong>Arithmetic operators</strong> perform mathematical calculations on numeric values.</li>
<li><strong>Comparison operators</strong> evaluate relationships between values, returning <strong>Boolean</strong> results.</li>
<li><strong>Boolean operators</strong> create compound logical expressions.</li>
<li><strong>Identity operators</strong> determine if two operands refer to the same object.</li>
<li><strong>Membership operators</strong> check for the presence of a value in a container.</li>
<li><strong>Bitwise operators</strong> manipulate data at the binary level.</li>
<li><strong>Concatenation and repetition operators</strong> manipulate sequence data types.</li>
<li><strong>Augmented assignment operators</strong> simplify expressions involving the same variable.</li>
</ul>
<hr />
<p><em>[ Improve Your Python With 🐍 Python Tricks 💌 – Get a short & sweet Python Trick delivered to your inbox every couple of days. <a href="https://realpython.com/python-tricks/?utm_source=realpython&utm_medium=rss&utm_campaign=footer">>> Click here to learn more and see examples</a> ]</em></p>
The Real Python Podcast – Episode #273: Advice for Writing Maintainable Python Code
https://realpython.com/podcasts/rpp/273/
2025-11-07T12:00:00+00:00
What are techniques for writing maintainable Python code? How do you make your Python more readable and easier to refactor? Christopher Trudeau is back on the show this week, bringing another batch of PyCoder's Weekly articles and projects.
<p>What are techniques for writing maintainable Python code? How do you make your Python more readable and easier to refactor? Christopher Trudeau is back on the show this week, bringing another batch of PyCoder's Weekly articles and projects.</p>
<hr />
<p><em>[ Improve Your Python With 🐍 Python Tricks 💌 – Get a short & sweet Python Trick delivered to your inbox every couple of days. <a href="https://realpython.com/python-tricks/?utm_source=realpython&utm_medium=rss&utm_campaign=footer">>> Click here to learn more and see examples</a> ]</em></p>
Quiz: Python MarkItDown: Convert Documents Into LLM-Ready Markdown
https://realpython.com/quizzes/python-markitdown/
2025-11-05T12:00:00+00:00
Practice MarkItDown basics. Convert PDFs, Word documents, Excel documents, and HTML documents to Markdown. Try the quiz.
<p>In this quiz, you’ll test your understanding of the <a href="https://realpython.com/python-markitdown/">Python MarkItDown: Convert Documents Into LLM-Ready Markdown</a> tutorial.</p>
<p>By working through this quiz, you’ll revisit how to install MarkItDown, convert documents to Markdown for your LLM workflows, and more.</p>
<hr />
<p><em>[ Improve Your Python With 🐍 Python Tricks 💌 – Get a short & sweet Python Trick delivered to your inbox every couple of days. <a href="https://realpython.com/python-tricks/?utm_source=realpython&utm_medium=rss&utm_campaign=footer">>> Click here to learn more and see examples</a> ]</em></p>
Building UIs in the Terminal With Python Textual
https://realpython.com/courses/building-uis-terminal-python-textual/
2025-11-04T14:00:00+00:00
Learn to build rich, interactive terminal UIs in Python with Textual: a powerful library for modern, event-driven TUIs.
<p>Have you ever wanted to create an app with an appealing interface that works in the command line? Welcome to Textual, a Python toolkit and framework for creating beautiful, functional <strong>text-based user interface (TUI)</strong> applications. The Textual library provides a powerful and flexible framework for building TUIs. It offers a variety of features that allow you to create interactive and engaging console applications.</p>
<p>In this video course, you’ll learn how to create, style, and enhance Textual apps with layouts, events, and actions.</p>
<p><strong>By the end of this video course, you’ll understand that:</strong></p>
<ul>
<li><strong>Python Textual</strong> is a framework for building terminal-based applications with interactive and visually appealing text interfaces.</li>
<li><strong>Textual works</strong> by providing a set of widgets, layouts, and styling options, enabling you to create responsive and interactive console apps.</li>
<li>Textual is useful for building efficient, <strong>platform-independent text-based user interfaces</strong> that work over remote connections and in low-resource environments.</li>
</ul>
<hr />
<p><em>[ Improve Your Python With 🐍 Python Tricks 💌 – Get a short & sweet Python Trick delivered to your inbox every couple of days. <a href="https://realpython.com/python-tricks/?utm_source=realpython&utm_medium=rss&utm_campaign=footer">>> Click here to learn more and see examples</a> ]</em></p>
The Real Python Podcast – Episode #272: Michael Kennedy: Managing Your Own Python Infrastructure
https://realpython.com/podcasts/rpp/272/
2025-10-31T12:00:00+00:00
How do you deploy your Python application without getting locked into an expensive cloud-based service? This week on the show, Michael Kennedy from the Talk Python podcast returns to discuss his new book, "Talk Python in Production."
<p>How do you deploy your Python application without getting locked into an expensive cloud-based service? This week on the show, Michael Kennedy from the Talk Python podcast returns to discuss his new book, "Talk Python in Production."</p>
<hr />
<p><em>[ Improve Your Python With 🐍 Python Tricks 💌 – Get a short & sweet Python Trick delivered to your inbox every couple of days. <a href="https://realpython.com/python-tricks/?utm_source=realpython&utm_medium=rss&utm_campaign=footer">>> Click here to learn more and see examples</a> ]</em></p>
Speed Up Python With Concurrency
https://realpython.com/courses/speed-python-concurrency/
2025-10-28T14:00:00+00:00
Learn what concurrency means in Python and why you might want to use it. You'll see a simple, non-concurrent approach and then look into why you'd want threading, asyncio, or multiprocessing.
<p>Concurrency is the act of having your computer do multiple things at the same time. If you’ve heard a lot of talk about <code>asyncio</code> <a href="https://realpython.com/python37-new-features/">being added to Python</a> but are curious how it compares to other concurrency methods or are wondering what concurrency is and how it might speed up your program, you’ve come to the right place.</p>
<p>In this course, you’ll learn the following:</p>
<ul>
<li>How I/O bound programs are effected by latency</li>
<li>Which concurrent programming patterns to use</li>
<li>What the differences are between the Python concurrency libraries</li>
<li>How to write code that uses the <code>threading</code>, <code>asyncio</code>, and <code>multiprocessing</code> libraries</li>
</ul>
<p>Sample code was tested using Python 3.13. Since much of the <code>asyncio</code> library has been in flux since Python 3.4, it’s recommended to use at least Python 3.9 for the <code>asyncio</code> portions of the course.</p>
<hr />
<p><em>[ Improve Your Python With 🐍 Python Tricks 💌 – Get a short & sweet Python Trick delivered to your inbox every couple of days. <a href="https://realpython.com/python-tricks/?utm_source=realpython&utm_medium=rss&utm_campaign=footer">>> Click here to learn more and see examples</a> ]</em></p>
The Real Python Podcast – Episode #271: Benchmarking Python 3.14 & Enabling Asyncio to Scale
https://realpython.com/podcasts/rpp/271/
2025-10-24T12:00:00+00:00
How does Python 3.14 perform under a few hand-crafted benchmarks? Does the performance of asyncio scale on the free-threaded build? Christopher Trudeau is back on the show this week, bringing another batch of PyCoder's Weekly articles and projects.
<p>How does Python 3.14 perform under a few hand-crafted benchmarks? Does the performance of asyncio scale on the free-threaded build? Christopher Trudeau is back on the show this week, bringing another batch of PyCoder's Weekly articles and projects.</p>
<hr />
<p><em>[ Improve Your Python With 🐍 Python Tricks 💌 – Get a short & sweet Python Trick delivered to your inbox every couple of days. <a href="https://realpython.com/python-tricks/?utm_source=realpython&utm_medium=rss&utm_campaign=footer">>> Click here to learn more and see examples</a> ]</em></p>
Investigating Quasar Data With Polars and Interactive marimo Notebooks
https://realpython.com/courses/investigating-quasar-data-polars-marimo-notebooks/
2025-10-21T14:00:00+00:00
Learn to visualize quasar redshift data by building an interactive marimo dashboard using Polars, pandas, and Matplotlib.
<p>Learn to visualize quasar redshift data by building an interactive marimo dashboard using Polars, pandas, and Matplotlib. You’ll practice retrieving, cleaning, and displaying data in your notebook. You’ll also build interactive UI components that live-update visualizations in the notebook.</p>
<hr />
<p><em>[ Improve Your Python With 🐍 Python Tricks 💌 – Get a short & sweet Python Trick delivered to your inbox every couple of days. <a href="https://realpython.com/python-tricks/?utm_source=realpython&utm_medium=rss&utm_campaign=footer">>> Click here to learn more and see examples</a> ]</em></p>
The Real Python Podcast – Episode #270: Evolving Teaching Python in the Classroom
https://realpython.com/podcasts/rpp/270/
2025-10-17T12:00:00+00:00
How is teaching young students Python changing with the advent of LLMs? This week on the show, Kelly Schuster-Paredes from the Teaching Python podcast joins us to discuss coding and AI in the classroom.
<p>How is teaching young students Python changing with the advent of LLMs? This week on the show, Kelly Schuster-Paredes from the Teaching Python podcast joins us to discuss coding and AI in the classroom.</p>
<hr />
<p><em>[ Improve Your Python With 🐍 Python Tricks 💌 – Get a short & sweet Python Trick delivered to your inbox every couple of days. <a href="https://realpython.com/python-tricks/?utm_source=realpython&utm_medium=rss&utm_campaign=footer">>> Click here to learn more and see examples</a> ]</em></p>
The Real Python Podcast – Episode #269: Python 3.14: Exploring the New Features
https://realpython.com/podcasts/rpp/269/
2025-10-10T12:00:00+00:00
Python 3.14 is here! Christopher Trudeau returns to discuss the new version with Real Python team member Bartosz Zaczyński. This year, Bartosz coordinated the series of preview articles with members of the Real Python team and wrote the showcase tutorial, "Python 3.14: Cool New Features for You to Try." Christopher's video course, "What's New in Python 3.14", covers the topics from the article and shows the new features in action.
<p>Python 3.14 is here! Christopher Trudeau returns to discuss the new version with Real Python team member Bartosz Zaczyński. This year, Bartosz coordinated the series of preview articles with members of the Real Python team and wrote the showcase tutorial, "Python 3.14: Cool New Features for You to Try." Christopher's video course, "What's New in Python 3.14", covers the topics from the article and shows the new features in action.</p>
<hr />
<p><em>[ Improve Your Python With 🐍 Python Tricks 💌 – Get a short & sweet Python Trick delivered to your inbox every couple of days. <a href="https://realpython.com/python-tricks/?utm_source=realpython&utm_medium=rss&utm_campaign=footer">>> Click here to learn more and see examples</a> ]</em></p>
The Real Python Podcast – Episode #268: Advice on Beginning to Learn Python
https://realpython.com/podcasts/rpp/268/
2025-10-03T12:00:00+00:00
What's changed about learning Python over the last few years? What new techniques and updated advice should beginners have as they start their journey? This week on the show, Stephen Gruppetta and Martin Breuss return to discuss beginning to learn Python.
<p>What's changed about learning Python over the last few years? What new techniques and updated advice should beginners have as they start their journey? This week on the show, Stephen Gruppetta and Martin Breuss return to discuss beginning to learn Python.</p>
<hr />
<p><em>[ Improve Your Python With 🐍 Python Tricks 💌 – Get a short & sweet Python Trick delivered to your inbox every couple of days. <a href="https://realpython.com/python-tricks/?utm_source=realpython&utm_medium=rss&utm_campaign=footer">>> Click here to learn more and see examples</a> ]</em></p>