1085 lines
94 KiB
HTML
1085 lines
94 KiB
HTML
<!DOCTYPE html>
|
||
|
||
<html lang="en" data-content_root="../">
|
||
<head>
|
||
<meta charset="utf-8" />
|
||
<meta name="viewport" content="width=device-width, initial-scale=1.0" /><meta name="viewport" content="width=device-width, initial-scale=1" />
|
||
<meta property="og:title" content="Design and History FAQ" />
|
||
<meta property="og:type" content="website" />
|
||
<meta property="og:url" content="https://docs.python.org/3/faq/design.html" />
|
||
<meta property="og:site_name" content="Python documentation" />
|
||
<meta property="og:description" content="Contents: Design and History FAQ- Why does Python use indentation for grouping of statements?, Why am I getting strange results with simple arithmetic operations?, Why are floating-point calculatio..." />
|
||
<meta property="og:image" content="https://docs.python.org/3/_static/og-image.png" />
|
||
<meta property="og:image:alt" content="Python documentation" />
|
||
<meta name="description" content="Contents: Design and History FAQ- Why does Python use indentation for grouping of statements?, Why am I getting strange results with simple arithmetic operations?, Why are floating-point calculatio..." />
|
||
<meta property="og:image:width" content="200">
|
||
<meta property="og:image:height" content="200">
|
||
<meta name="theme-color" content="#3776ab">
|
||
|
||
<title>Design and History FAQ — Python 3.13.3 documentation</title><meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||
|
||
<link rel="stylesheet" type="text/css" href="../_static/pygments.css?v=b86133f3" />
|
||
<link rel="stylesheet" type="text/css" href="../_static/pydoctheme.css?v=23252803" />
|
||
<link id="pygments_dark_css" media="(prefers-color-scheme: dark)" rel="stylesheet" type="text/css" href="../_static/pygments_dark.css?v=5349f25f" />
|
||
|
||
<script src="../_static/documentation_options.js?v=5d57ca2d"></script>
|
||
<script src="../_static/doctools.js?v=9bcbadda"></script>
|
||
<script src="../_static/sphinx_highlight.js?v=dc90522c"></script>
|
||
|
||
<script src="../_static/sidebar.js"></script>
|
||
|
||
<link rel="search" type="application/opensearchdescription+xml"
|
||
title="Search within Python 3.13.3 documentation"
|
||
href="../_static/opensearch.xml"/>
|
||
<link rel="author" title="About these documents" href="../about.html" />
|
||
<link rel="index" title="Index" href="../genindex.html" />
|
||
<link rel="search" title="Search" href="../search.html" />
|
||
<link rel="copyright" title="Copyright" href="../copyright.html" />
|
||
<link rel="next" title="Library and Extension FAQ" href="library.html" />
|
||
<link rel="prev" title="Programming FAQ" href="programming.html" />
|
||
|
||
<link rel="canonical" href="https://docs.python.org/3/faq/design.html">
|
||
|
||
|
||
|
||
|
||
|
||
<style>
|
||
@media only screen {
|
||
table.full-width-table {
|
||
width: 100%;
|
||
}
|
||
}
|
||
</style>
|
||
<link rel="stylesheet" href="../_static/pydoctheme_dark.css" media="(prefers-color-scheme: dark)" id="pydoctheme_dark_css">
|
||
<link rel="shortcut icon" type="image/png" href="../_static/py.svg" />
|
||
<script type="text/javascript" src="../_static/copybutton.js"></script>
|
||
<script type="text/javascript" src="../_static/menu.js"></script>
|
||
<script type="text/javascript" src="../_static/search-focus.js"></script>
|
||
<script type="text/javascript" src="../_static/themetoggle.js"></script>
|
||
<script type="text/javascript" src="../_static/rtd_switcher.js"></script>
|
||
<meta name="readthedocs-addons-api-version" content="1">
|
||
|
||
</head>
|
||
<body>
|
||
<div class="mobile-nav">
|
||
<input type="checkbox" id="menuToggler" class="toggler__input" aria-controls="navigation"
|
||
aria-pressed="false" aria-expanded="false" role="button" aria-label="Menu" />
|
||
<nav class="nav-content" role="navigation">
|
||
<label for="menuToggler" class="toggler__label">
|
||
<span></span>
|
||
</label>
|
||
<span class="nav-items-wrapper">
|
||
<a href="https://www.python.org/" class="nav-logo">
|
||
<img src="../_static/py.svg" alt="Python logo"/>
|
||
</a>
|
||
<span class="version_switcher_placeholder"></span>
|
||
<form role="search" class="search" action="../search.html" method="get">
|
||
<svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" class="search-icon">
|
||
<path fill-rule="nonzero" fill="currentColor" d="M15.5 14h-.79l-.28-.27a6.5 6.5 0 001.48-5.34c-.47-2.78-2.79-5-5.59-5.34a6.505 6.505 0 00-7.27 7.27c.34 2.8 2.56 5.12 5.34 5.59a6.5 6.5 0 005.34-1.48l.27.28v.79l4.25 4.25c.41.41 1.08.41 1.49 0 .41-.41.41-1.08 0-1.49L15.5 14zm-6 0C7.01 14 5 11.99 5 9.5S7.01 5 9.5 5 14 7.01 14 9.5 11.99 14 9.5 14z"></path>
|
||
</svg>
|
||
<input placeholder="Quick search" aria-label="Quick search" type="search" name="q" />
|
||
<input type="submit" value="Go"/>
|
||
</form>
|
||
</span>
|
||
</nav>
|
||
<div class="menu-wrapper">
|
||
<nav class="menu" role="navigation" aria-label="main navigation">
|
||
<div class="language_switcher_placeholder"></div>
|
||
|
||
<label class="theme-selector-label">
|
||
Theme
|
||
<select class="theme-selector" oninput="activateTheme(this.value)">
|
||
<option value="auto" selected>Auto</option>
|
||
<option value="light">Light</option>
|
||
<option value="dark">Dark</option>
|
||
</select>
|
||
</label>
|
||
<div>
|
||
<h3><a href="../contents.html">Table of Contents</a></h3>
|
||
<ul>
|
||
<li><a class="reference internal" href="#">Design and History FAQ</a><ul>
|
||
<li><a class="reference internal" href="#why-does-python-use-indentation-for-grouping-of-statements">Why does Python use indentation for grouping of statements?</a></li>
|
||
<li><a class="reference internal" href="#why-am-i-getting-strange-results-with-simple-arithmetic-operations">Why am I getting strange results with simple arithmetic operations?</a></li>
|
||
<li><a class="reference internal" href="#why-are-floating-point-calculations-so-inaccurate">Why are floating-point calculations so inaccurate?</a></li>
|
||
<li><a class="reference internal" href="#why-are-python-strings-immutable">Why are Python strings immutable?</a></li>
|
||
<li><a class="reference internal" href="#why-must-self-be-used-explicitly-in-method-definitions-and-calls">Why must ‘self’ be used explicitly in method definitions and calls?</a></li>
|
||
<li><a class="reference internal" href="#why-can-t-i-use-an-assignment-in-an-expression">Why can’t I use an assignment in an expression?</a></li>
|
||
<li><a class="reference internal" href="#why-does-python-use-methods-for-some-functionality-e-g-list-index-but-functions-for-other-e-g-len-list">Why does Python use methods for some functionality (e.g. list.index()) but functions for other (e.g. len(list))?</a></li>
|
||
<li><a class="reference internal" href="#why-is-join-a-string-method-instead-of-a-list-or-tuple-method">Why is join() a string method instead of a list or tuple method?</a></li>
|
||
<li><a class="reference internal" href="#how-fast-are-exceptions">How fast are exceptions?</a></li>
|
||
<li><a class="reference internal" href="#why-isn-t-there-a-switch-or-case-statement-in-python">Why isn’t there a switch or case statement in Python?</a></li>
|
||
<li><a class="reference internal" href="#can-t-you-emulate-threads-in-the-interpreter-instead-of-relying-on-an-os-specific-thread-implementation">Can’t you emulate threads in the interpreter instead of relying on an OS-specific thread implementation?</a></li>
|
||
<li><a class="reference internal" href="#why-can-t-lambda-expressions-contain-statements">Why can’t lambda expressions contain statements?</a></li>
|
||
<li><a class="reference internal" href="#can-python-be-compiled-to-machine-code-c-or-some-other-language">Can Python be compiled to machine code, C or some other language?</a></li>
|
||
<li><a class="reference internal" href="#how-does-python-manage-memory">How does Python manage memory?</a></li>
|
||
<li><a class="reference internal" href="#why-doesn-t-cpython-use-a-more-traditional-garbage-collection-scheme">Why doesn’t CPython use a more traditional garbage collection scheme?</a></li>
|
||
<li><a class="reference internal" href="#why-isn-t-all-memory-freed-when-cpython-exits">Why isn’t all memory freed when CPython exits?</a></li>
|
||
<li><a class="reference internal" href="#why-are-there-separate-tuple-and-list-data-types">Why are there separate tuple and list data types?</a></li>
|
||
<li><a class="reference internal" href="#how-are-lists-implemented-in-cpython">How are lists implemented in CPython?</a></li>
|
||
<li><a class="reference internal" href="#how-are-dictionaries-implemented-in-cpython">How are dictionaries implemented in CPython?</a></li>
|
||
<li><a class="reference internal" href="#why-must-dictionary-keys-be-immutable">Why must dictionary keys be immutable?</a></li>
|
||
<li><a class="reference internal" href="#why-doesn-t-list-sort-return-the-sorted-list">Why doesn’t list.sort() return the sorted list?</a></li>
|
||
<li><a class="reference internal" href="#how-do-you-specify-and-enforce-an-interface-spec-in-python">How do you specify and enforce an interface spec in Python?</a></li>
|
||
<li><a class="reference internal" href="#why-is-there-no-goto">Why is there no goto?</a></li>
|
||
<li><a class="reference internal" href="#why-can-t-raw-strings-r-strings-end-with-a-backslash">Why can’t raw strings (r-strings) end with a backslash?</a></li>
|
||
<li><a class="reference internal" href="#why-doesn-t-python-have-a-with-statement-for-attribute-assignments">Why doesn’t Python have a “with” statement for attribute assignments?</a></li>
|
||
<li><a class="reference internal" href="#why-don-t-generators-support-the-with-statement">Why don’t generators support the with statement?</a></li>
|
||
<li><a class="reference internal" href="#why-are-colons-required-for-the-if-while-def-class-statements">Why are colons required for the if/while/def/class statements?</a></li>
|
||
<li><a class="reference internal" href="#why-does-python-allow-commas-at-the-end-of-lists-and-tuples">Why does Python allow commas at the end of lists and tuples?</a></li>
|
||
</ul>
|
||
</li>
|
||
</ul>
|
||
|
||
</div>
|
||
<div>
|
||
<h4>Previous topic</h4>
|
||
<p class="topless"><a href="programming.html"
|
||
title="previous chapter">Programming FAQ</a></p>
|
||
</div>
|
||
<div>
|
||
<h4>Next topic</h4>
|
||
<p class="topless"><a href="library.html"
|
||
title="next chapter">Library and Extension FAQ</a></p>
|
||
</div>
|
||
<div role="note" aria-label="source link">
|
||
<h3>This Page</h3>
|
||
<ul class="this-page-menu">
|
||
<li><a href="../bugs.html">Report a Bug</a></li>
|
||
<li>
|
||
<a href="https://github.com/python/cpython/blob/main/Doc/faq/design.rst"
|
||
rel="nofollow">Show Source
|
||
</a>
|
||
</li>
|
||
</ul>
|
||
</div>
|
||
</nav>
|
||
</div>
|
||
</div>
|
||
|
||
|
||
<div class="related" role="navigation" aria-label="Related">
|
||
<h3>Navigation</h3>
|
||
<ul>
|
||
<li class="right" style="margin-right: 10px">
|
||
<a href="../genindex.html" title="General Index"
|
||
accesskey="I">index</a></li>
|
||
<li class="right" >
|
||
<a href="../py-modindex.html" title="Python Module Index"
|
||
>modules</a> |</li>
|
||
<li class="right" >
|
||
<a href="library.html" title="Library and Extension FAQ"
|
||
accesskey="N">next</a> |</li>
|
||
<li class="right" >
|
||
<a href="programming.html" title="Programming FAQ"
|
||
accesskey="P">previous</a> |</li>
|
||
|
||
<li><img src="../_static/py.svg" alt="Python logo" style="vertical-align: middle; margin-top: -1px"/></li>
|
||
<li><a href="https://www.python.org/">Python</a> »</li>
|
||
<li class="switchers">
|
||
<div class="language_switcher_placeholder"></div>
|
||
<div class="version_switcher_placeholder"></div>
|
||
</li>
|
||
<li>
|
||
|
||
</li>
|
||
<li id="cpython-language-and-version">
|
||
<a href="../index.html">3.13.3 Documentation</a> »
|
||
</li>
|
||
|
||
<li class="nav-item nav-item-1"><a href="index.html" accesskey="U">Python Frequently Asked Questions</a> »</li>
|
||
<li class="nav-item nav-item-this"><a href="">Design and History FAQ</a></li>
|
||
<li class="right">
|
||
|
||
|
||
<div class="inline-search" role="search">
|
||
<form class="inline-search" action="../search.html" method="get">
|
||
<input placeholder="Quick search" aria-label="Quick search" type="search" name="q" id="search-box" />
|
||
<input type="submit" value="Go" />
|
||
</form>
|
||
</div>
|
||
|
|
||
</li>
|
||
<li class="right">
|
||
<label class="theme-selector-label">
|
||
Theme
|
||
<select class="theme-selector" oninput="activateTheme(this.value)">
|
||
<option value="auto" selected>Auto</option>
|
||
<option value="light">Light</option>
|
||
<option value="dark">Dark</option>
|
||
</select>
|
||
</label> |</li>
|
||
|
||
</ul>
|
||
</div>
|
||
|
||
<div class="document">
|
||
<div class="documentwrapper">
|
||
<div class="bodywrapper">
|
||
<div class="body" role="main">
|
||
|
||
<section id="design-and-history-faq">
|
||
<h1><a class="toc-backref" href="#id2" role="doc-backlink">Design and History FAQ</a><a class="headerlink" href="#design-and-history-faq" title="Link to this heading">¶</a></h1>
|
||
<nav class="contents" id="contents">
|
||
<p class="topic-title">Contents</p>
|
||
<ul class="simple">
|
||
<li><p><a class="reference internal" href="#design-and-history-faq" id="id2">Design and History FAQ</a></p>
|
||
<ul>
|
||
<li><p><a class="reference internal" href="#why-does-python-use-indentation-for-grouping-of-statements" id="id3">Why does Python use indentation for grouping of statements?</a></p></li>
|
||
<li><p><a class="reference internal" href="#why-am-i-getting-strange-results-with-simple-arithmetic-operations" id="id4">Why am I getting strange results with simple arithmetic operations?</a></p></li>
|
||
<li><p><a class="reference internal" href="#why-are-floating-point-calculations-so-inaccurate" id="id5">Why are floating-point calculations so inaccurate?</a></p></li>
|
||
<li><p><a class="reference internal" href="#why-are-python-strings-immutable" id="id6">Why are Python strings immutable?</a></p></li>
|
||
<li><p><a class="reference internal" href="#why-must-self-be-used-explicitly-in-method-definitions-and-calls" id="id7">Why must ‘self’ be used explicitly in method definitions and calls?</a></p></li>
|
||
<li><p><a class="reference internal" href="#why-can-t-i-use-an-assignment-in-an-expression" id="id8">Why can’t I use an assignment in an expression?</a></p></li>
|
||
<li><p><a class="reference internal" href="#why-does-python-use-methods-for-some-functionality-e-g-list-index-but-functions-for-other-e-g-len-list" id="id9">Why does Python use methods for some functionality (e.g. list.index()) but functions for other (e.g. len(list))?</a></p></li>
|
||
<li><p><a class="reference internal" href="#why-is-join-a-string-method-instead-of-a-list-or-tuple-method" id="id10">Why is join() a string method instead of a list or tuple method?</a></p></li>
|
||
<li><p><a class="reference internal" href="#how-fast-are-exceptions" id="id11">How fast are exceptions?</a></p></li>
|
||
<li><p><a class="reference internal" href="#why-isn-t-there-a-switch-or-case-statement-in-python" id="id12">Why isn’t there a switch or case statement in Python?</a></p></li>
|
||
<li><p><a class="reference internal" href="#can-t-you-emulate-threads-in-the-interpreter-instead-of-relying-on-an-os-specific-thread-implementation" id="id13">Can’t you emulate threads in the interpreter instead of relying on an OS-specific thread implementation?</a></p></li>
|
||
<li><p><a class="reference internal" href="#why-can-t-lambda-expressions-contain-statements" id="id14">Why can’t lambda expressions contain statements?</a></p></li>
|
||
<li><p><a class="reference internal" href="#can-python-be-compiled-to-machine-code-c-or-some-other-language" id="id15">Can Python be compiled to machine code, C or some other language?</a></p></li>
|
||
<li><p><a class="reference internal" href="#how-does-python-manage-memory" id="id16">How does Python manage memory?</a></p></li>
|
||
<li><p><a class="reference internal" href="#why-doesn-t-cpython-use-a-more-traditional-garbage-collection-scheme" id="id17">Why doesn’t CPython use a more traditional garbage collection scheme?</a></p></li>
|
||
<li><p><a class="reference internal" href="#why-isn-t-all-memory-freed-when-cpython-exits" id="id18">Why isn’t all memory freed when CPython exits?</a></p></li>
|
||
<li><p><a class="reference internal" href="#why-are-there-separate-tuple-and-list-data-types" id="id19">Why are there separate tuple and list data types?</a></p></li>
|
||
<li><p><a class="reference internal" href="#how-are-lists-implemented-in-cpython" id="id20">How are lists implemented in CPython?</a></p></li>
|
||
<li><p><a class="reference internal" href="#how-are-dictionaries-implemented-in-cpython" id="id21">How are dictionaries implemented in CPython?</a></p></li>
|
||
<li><p><a class="reference internal" href="#why-must-dictionary-keys-be-immutable" id="id22">Why must dictionary keys be immutable?</a></p></li>
|
||
<li><p><a class="reference internal" href="#why-doesn-t-list-sort-return-the-sorted-list" id="id23">Why doesn’t list.sort() return the sorted list?</a></p></li>
|
||
<li><p><a class="reference internal" href="#how-do-you-specify-and-enforce-an-interface-spec-in-python" id="id24">How do you specify and enforce an interface spec in Python?</a></p></li>
|
||
<li><p><a class="reference internal" href="#why-is-there-no-goto" id="id25">Why is there no goto?</a></p></li>
|
||
<li><p><a class="reference internal" href="#why-can-t-raw-strings-r-strings-end-with-a-backslash" id="id26">Why can’t raw strings (r-strings) end with a backslash?</a></p></li>
|
||
<li><p><a class="reference internal" href="#why-doesn-t-python-have-a-with-statement-for-attribute-assignments" id="id27">Why doesn’t Python have a “with” statement for attribute assignments?</a></p></li>
|
||
<li><p><a class="reference internal" href="#why-don-t-generators-support-the-with-statement" id="id28">Why don’t generators support the with statement?</a></p></li>
|
||
<li><p><a class="reference internal" href="#why-are-colons-required-for-the-if-while-def-class-statements" id="id29">Why are colons required for the if/while/def/class statements?</a></p></li>
|
||
<li><p><a class="reference internal" href="#why-does-python-allow-commas-at-the-end-of-lists-and-tuples" id="id30">Why does Python allow commas at the end of lists and tuples?</a></p></li>
|
||
</ul>
|
||
</li>
|
||
</ul>
|
||
</nav>
|
||
<section id="why-does-python-use-indentation-for-grouping-of-statements">
|
||
<h2><a class="toc-backref" href="#id3" role="doc-backlink">Why does Python use indentation for grouping of statements?</a><a class="headerlink" href="#why-does-python-use-indentation-for-grouping-of-statements" title="Link to this heading">¶</a></h2>
|
||
<p>Guido van Rossum believes that using indentation for grouping is extremely
|
||
elegant and contributes a lot to the clarity of the average Python program.
|
||
Most people learn to love this feature after a while.</p>
|
||
<p>Since there are no begin/end brackets there cannot be a disagreement between
|
||
grouping perceived by the parser and the human reader. Occasionally C
|
||
programmers will encounter a fragment of code like this:</p>
|
||
<div class="highlight-python3 notranslate"><div class="highlight"><pre><span></span><span class="k">if</span> <span class="p">(</span><span class="n">x</span> <span class="o"><=</span> <span class="n">y</span><span class="p">)</span>
|
||
<span class="n">x</span><span class="o">++</span><span class="p">;</span>
|
||
<span class="n">y</span><span class="o">--</span><span class="p">;</span>
|
||
<span class="n">z</span><span class="o">++</span><span class="p">;</span>
|
||
</pre></div>
|
||
</div>
|
||
<p>Only the <code class="docutils literal notranslate"><span class="pre">x++</span></code> statement is executed if the condition is true, but the
|
||
indentation leads many to believe otherwise. Even experienced C programmers will
|
||
sometimes stare at it a long time wondering as to why <code class="docutils literal notranslate"><span class="pre">y</span></code> is being decremented even
|
||
for <code class="docutils literal notranslate"><span class="pre">x</span> <span class="pre">></span> <span class="pre">y</span></code>.</p>
|
||
<p>Because there are no begin/end brackets, Python is much less prone to
|
||
coding-style conflicts. In C there are many different ways to place the braces.
|
||
After becoming used to reading and writing code using a particular style,
|
||
it is normal to feel somewhat uneasy when reading (or being required to write)
|
||
in a different one.</p>
|
||
<p>Many coding styles place begin/end brackets on a line by themselves. This makes
|
||
programs considerably longer and wastes valuable screen space, making it harder
|
||
to get a good overview of a program. Ideally, a function should fit on one
|
||
screen (say, 20–30 lines). 20 lines of Python can do a lot more work than 20
|
||
lines of C. This is not solely due to the lack of begin/end brackets – the
|
||
lack of declarations and the high-level data types are also responsible – but
|
||
the indentation-based syntax certainly helps.</p>
|
||
</section>
|
||
<section id="why-am-i-getting-strange-results-with-simple-arithmetic-operations">
|
||
<h2><a class="toc-backref" href="#id4" role="doc-backlink">Why am I getting strange results with simple arithmetic operations?</a><a class="headerlink" href="#why-am-i-getting-strange-results-with-simple-arithmetic-operations" title="Link to this heading">¶</a></h2>
|
||
<p>See the next question.</p>
|
||
</section>
|
||
<section id="why-are-floating-point-calculations-so-inaccurate">
|
||
<h2><a class="toc-backref" href="#id5" role="doc-backlink">Why are floating-point calculations so inaccurate?</a><a class="headerlink" href="#why-are-floating-point-calculations-so-inaccurate" title="Link to this heading">¶</a></h2>
|
||
<p>Users are often surprised by results like this:</p>
|
||
<div class="highlight-python3 notranslate"><div class="highlight"><pre><span></span><span class="gp">>>> </span><span class="mf">1.2</span> <span class="o">-</span> <span class="mf">1.0</span>
|
||
<span class="go">0.19999999999999996</span>
|
||
</pre></div>
|
||
</div>
|
||
<p>and think it is a bug in Python. It’s not. This has little to do with Python,
|
||
and much more to do with how the underlying platform handles floating-point
|
||
numbers.</p>
|
||
<p>The <a class="reference internal" href="../library/functions.html#float" title="float"><code class="xref py py-class docutils literal notranslate"><span class="pre">float</span></code></a> type in CPython uses a C <code class="docutils literal notranslate"><span class="pre">double</span></code> for storage. A
|
||
<a class="reference internal" href="../library/functions.html#float" title="float"><code class="xref py py-class docutils literal notranslate"><span class="pre">float</span></code></a> object’s value is stored in binary floating-point with a fixed
|
||
precision (typically 53 bits) and Python uses C operations, which in turn rely
|
||
on the hardware implementation in the processor, to perform floating-point
|
||
operations. This means that as far as floating-point operations are concerned,
|
||
Python behaves like many popular languages including C and Java.</p>
|
||
<p>Many numbers that can be written easily in decimal notation cannot be expressed
|
||
exactly in binary floating point. For example, after:</p>
|
||
<div class="highlight-python3 notranslate"><div class="highlight"><pre><span></span><span class="gp">>>> </span><span class="n">x</span> <span class="o">=</span> <span class="mf">1.2</span>
|
||
</pre></div>
|
||
</div>
|
||
<p>the value stored for <code class="docutils literal notranslate"><span class="pre">x</span></code> is a (very good) approximation to the decimal value
|
||
<code class="docutils literal notranslate"><span class="pre">1.2</span></code>, but is not exactly equal to it. On a typical machine, the actual
|
||
stored value is:</p>
|
||
<div class="highlight-python3 notranslate"><div class="highlight"><pre><span></span><span class="mf">1.0011001100110011001100110011001100110011001100110011</span> <span class="p">(</span><span class="n">binary</span><span class="p">)</span>
|
||
</pre></div>
|
||
</div>
|
||
<p>which is exactly:</p>
|
||
<div class="highlight-python3 notranslate"><div class="highlight"><pre><span></span><span class="mf">1.1999999999999999555910790149937383830547332763671875</span> <span class="p">(</span><span class="n">decimal</span><span class="p">)</span>
|
||
</pre></div>
|
||
</div>
|
||
<p>The typical precision of 53 bits provides Python floats with 15–16
|
||
decimal digits of accuracy.</p>
|
||
<p>For a fuller explanation, please see the <a class="reference internal" href="../tutorial/floatingpoint.html#tut-fp-issues"><span class="std std-ref">floating-point arithmetic</span></a> chapter in the Python tutorial.</p>
|
||
</section>
|
||
<section id="why-are-python-strings-immutable">
|
||
<h2><a class="toc-backref" href="#id6" role="doc-backlink">Why are Python strings immutable?</a><a class="headerlink" href="#why-are-python-strings-immutable" title="Link to this heading">¶</a></h2>
|
||
<p>There are several advantages.</p>
|
||
<p>One is performance: knowing that a string is immutable means we can allocate
|
||
space for it at creation time, and the storage requirements are fixed and
|
||
unchanging. This is also one of the reasons for the distinction between tuples
|
||
and lists.</p>
|
||
<p>Another advantage is that strings in Python are considered as “elemental” as
|
||
numbers. No amount of activity will change the value 8 to anything else, and in
|
||
Python, no amount of activity will change the string “eight” to anything else.</p>
|
||
</section>
|
||
<section id="why-must-self-be-used-explicitly-in-method-definitions-and-calls">
|
||
<span id="why-self"></span><h2><a class="toc-backref" href="#id7" role="doc-backlink">Why must ‘self’ be used explicitly in method definitions and calls?</a><a class="headerlink" href="#why-must-self-be-used-explicitly-in-method-definitions-and-calls" title="Link to this heading">¶</a></h2>
|
||
<p>The idea was borrowed from Modula-3. It turns out to be very useful, for a
|
||
variety of reasons.</p>
|
||
<p>First, it’s more obvious that you are using a method or instance attribute
|
||
instead of a local variable. Reading <code class="docutils literal notranslate"><span class="pre">self.x</span></code> or <code class="docutils literal notranslate"><span class="pre">self.meth()</span></code> makes it
|
||
absolutely clear that an instance variable or method is used even if you don’t
|
||
know the class definition by heart. In C++, you can sort of tell by the lack of
|
||
a local variable declaration (assuming globals are rare or easily recognizable)
|
||
– but in Python, there are no local variable declarations, so you’d have to
|
||
look up the class definition to be sure. Some C++ and Java coding standards
|
||
call for instance attributes to have an <code class="docutils literal notranslate"><span class="pre">m_</span></code> prefix, so this explicitness is
|
||
still useful in those languages, too.</p>
|
||
<p>Second, it means that no special syntax is necessary if you want to explicitly
|
||
reference or call the method from a particular class. In C++, if you want to
|
||
use a method from a base class which is overridden in a derived class, you have
|
||
to use the <code class="docutils literal notranslate"><span class="pre">::</span></code> operator – in Python you can write
|
||
<code class="docutils literal notranslate"><span class="pre">baseclass.methodname(self,</span> <span class="pre"><argument</span> <span class="pre">list>)</span></code>. This is particularly useful
|
||
for <a class="reference internal" href="../reference/datamodel.html#object.__init__" title="object.__init__"><code class="xref py py-meth docutils literal notranslate"><span class="pre">__init__()</span></code></a> methods, and in general in cases where a derived class
|
||
method wants to extend the base class method of the same name and thus has to
|
||
call the base class method somehow.</p>
|
||
<p>Finally, for instance variables it solves a syntactic problem with assignment:
|
||
since local variables in Python are (by definition!) those variables to which a
|
||
value is assigned in a function body (and that aren’t explicitly declared
|
||
global), there has to be some way to tell the interpreter that an assignment was
|
||
meant to assign to an instance variable instead of to a local variable, and it
|
||
should preferably be syntactic (for efficiency reasons). C++ does this through
|
||
declarations, but Python doesn’t have declarations and it would be a pity having
|
||
to introduce them just for this purpose. Using the explicit <code class="docutils literal notranslate"><span class="pre">self.var</span></code> solves
|
||
this nicely. Similarly, for using instance variables, having to write
|
||
<code class="docutils literal notranslate"><span class="pre">self.var</span></code> means that references to unqualified names inside a method don’t
|
||
have to search the instance’s directories. To put it another way, local
|
||
variables and instance variables live in two different namespaces, and you need
|
||
to tell Python which namespace to use.</p>
|
||
</section>
|
||
<section id="why-can-t-i-use-an-assignment-in-an-expression">
|
||
<span id="id1"></span><h2><a class="toc-backref" href="#id8" role="doc-backlink">Why can’t I use an assignment in an expression?</a><a class="headerlink" href="#why-can-t-i-use-an-assignment-in-an-expression" title="Link to this heading">¶</a></h2>
|
||
<p>Starting in Python 3.8, you can!</p>
|
||
<p>Assignment expressions using the walrus operator <code class="docutils literal notranslate"><span class="pre">:=</span></code> assign a variable in an
|
||
expression:</p>
|
||
<div class="highlight-python3 notranslate"><div class="highlight"><pre><span></span><span class="k">while</span> <span class="n">chunk</span> <span class="o">:=</span> <span class="n">fp</span><span class="o">.</span><span class="n">read</span><span class="p">(</span><span class="mi">200</span><span class="p">):</span>
|
||
<span class="nb">print</span><span class="p">(</span><span class="n">chunk</span><span class="p">)</span>
|
||
</pre></div>
|
||
</div>
|
||
<p>See <span class="target" id="index-0"></span><a class="pep reference external" href="https://peps.python.org/pep-0572/"><strong>PEP 572</strong></a> for more information.</p>
|
||
</section>
|
||
<section id="why-does-python-use-methods-for-some-functionality-e-g-list-index-but-functions-for-other-e-g-len-list">
|
||
<h2><a class="toc-backref" href="#id9" role="doc-backlink">Why does Python use methods for some functionality (e.g. list.index()) but functions for other (e.g. len(list))?</a><a class="headerlink" href="#why-does-python-use-methods-for-some-functionality-e-g-list-index-but-functions-for-other-e-g-len-list" title="Link to this heading">¶</a></h2>
|
||
<p>As Guido said:</p>
|
||
<blockquote>
|
||
<div><p>(a) For some operations, prefix notation just reads better than
|
||
postfix – prefix (and infix!) operations have a long tradition in
|
||
mathematics which likes notations where the visuals help the
|
||
mathematician thinking about a problem. Compare the easy with which we
|
||
rewrite a formula like x*(a+b) into x*a + x*b to the clumsiness of
|
||
doing the same thing using a raw OO notation.</p>
|
||
<p>(b) When I read code that says len(x) I <em>know</em> that it is asking for
|
||
the length of something. This tells me two things: the result is an
|
||
integer, and the argument is some kind of container. To the contrary,
|
||
when I read x.len(), I have to already know that x is some kind of
|
||
container implementing an interface or inheriting from a class that
|
||
has a standard len(). Witness the confusion we occasionally have when
|
||
a class that is not implementing a mapping has a get() or keys()
|
||
method, or something that isn’t a file has a write() method.</p>
|
||
<p class="attribution">—<a class="reference external" href="https://mail.python.org/pipermail/python-3000/2006-November/004643.html">https://mail.python.org/pipermail/python-3000/2006-November/004643.html</a></p>
|
||
</div></blockquote>
|
||
</section>
|
||
<section id="why-is-join-a-string-method-instead-of-a-list-or-tuple-method">
|
||
<h2><a class="toc-backref" href="#id10" role="doc-backlink">Why is join() a string method instead of a list or tuple method?</a><a class="headerlink" href="#why-is-join-a-string-method-instead-of-a-list-or-tuple-method" title="Link to this heading">¶</a></h2>
|
||
<p>Strings became much more like other standard types starting in Python 1.6, when
|
||
methods were added which give the same functionality that has always been
|
||
available using the functions of the string module. Most of these new methods
|
||
have been widely accepted, but the one which appears to make some programmers
|
||
feel uncomfortable is:</p>
|
||
<div class="highlight-python3 notranslate"><div class="highlight"><pre><span></span><span class="s2">", "</span><span class="o">.</span><span class="n">join</span><span class="p">([</span><span class="s1">'1'</span><span class="p">,</span> <span class="s1">'2'</span><span class="p">,</span> <span class="s1">'4'</span><span class="p">,</span> <span class="s1">'8'</span><span class="p">,</span> <span class="s1">'16'</span><span class="p">])</span>
|
||
</pre></div>
|
||
</div>
|
||
<p>which gives the result:</p>
|
||
<div class="highlight-python3 notranslate"><div class="highlight"><pre><span></span><span class="s2">"1, 2, 4, 8, 16"</span>
|
||
</pre></div>
|
||
</div>
|
||
<p>There are two common arguments against this usage.</p>
|
||
<p>The first runs along the lines of: “It looks really ugly using a method of a
|
||
string literal (string constant)”, to which the answer is that it might, but a
|
||
string literal is just a fixed value. If the methods are to be allowed on names
|
||
bound to strings there is no logical reason to make them unavailable on
|
||
literals.</p>
|
||
<p>The second objection is typically cast as: “I am really telling a sequence to
|
||
join its members together with a string constant”. Sadly, you aren’t. For some
|
||
reason there seems to be much less difficulty with having <a class="reference internal" href="../library/stdtypes.html#str.split" title="str.split"><code class="xref py py-meth docutils literal notranslate"><span class="pre">split()</span></code></a> as
|
||
a string method, since in that case it is easy to see that</p>
|
||
<div class="highlight-python3 notranslate"><div class="highlight"><pre><span></span><span class="s2">"1, 2, 4, 8, 16"</span><span class="o">.</span><span class="n">split</span><span class="p">(</span><span class="s2">", "</span><span class="p">)</span>
|
||
</pre></div>
|
||
</div>
|
||
<p>is an instruction to a string literal to return the substrings delimited by the
|
||
given separator (or, by default, arbitrary runs of white space).</p>
|
||
<p><a class="reference internal" href="../library/stdtypes.html#str.join" title="str.join"><code class="xref py py-meth docutils literal notranslate"><span class="pre">join()</span></code></a> is a string method because in using it you are telling the
|
||
separator string to iterate over a sequence of strings and insert itself between
|
||
adjacent elements. This method can be used with any argument which obeys the
|
||
rules for sequence objects, including any new classes you might define yourself.
|
||
Similar methods exist for bytes and bytearray objects.</p>
|
||
</section>
|
||
<section id="how-fast-are-exceptions">
|
||
<h2><a class="toc-backref" href="#id11" role="doc-backlink">How fast are exceptions?</a><a class="headerlink" href="#how-fast-are-exceptions" title="Link to this heading">¶</a></h2>
|
||
<p>A <a class="reference internal" href="../reference/compound_stmts.html#try"><code class="xref std std-keyword docutils literal notranslate"><span class="pre">try</span></code></a>/<a class="reference internal" href="../reference/compound_stmts.html#except"><code class="xref std std-keyword docutils literal notranslate"><span class="pre">except</span></code></a> block is extremely efficient if no exceptions
|
||
are raised. Actually
|
||
catching an exception is expensive. In versions of Python prior to 2.0 it was
|
||
common to use this idiom:</p>
|
||
<div class="highlight-python3 notranslate"><div class="highlight"><pre><span></span><span class="k">try</span><span class="p">:</span>
|
||
<span class="n">value</span> <span class="o">=</span> <span class="n">mydict</span><span class="p">[</span><span class="n">key</span><span class="p">]</span>
|
||
<span class="k">except</span> <span class="ne">KeyError</span><span class="p">:</span>
|
||
<span class="n">mydict</span><span class="p">[</span><span class="n">key</span><span class="p">]</span> <span class="o">=</span> <span class="n">getvalue</span><span class="p">(</span><span class="n">key</span><span class="p">)</span>
|
||
<span class="n">value</span> <span class="o">=</span> <span class="n">mydict</span><span class="p">[</span><span class="n">key</span><span class="p">]</span>
|
||
</pre></div>
|
||
</div>
|
||
<p>This only made sense when you expected the dict to have the key almost all the
|
||
time. If that wasn’t the case, you coded it like this:</p>
|
||
<div class="highlight-python3 notranslate"><div class="highlight"><pre><span></span><span class="k">if</span> <span class="n">key</span> <span class="ow">in</span> <span class="n">mydict</span><span class="p">:</span>
|
||
<span class="n">value</span> <span class="o">=</span> <span class="n">mydict</span><span class="p">[</span><span class="n">key</span><span class="p">]</span>
|
||
<span class="k">else</span><span class="p">:</span>
|
||
<span class="n">value</span> <span class="o">=</span> <span class="n">mydict</span><span class="p">[</span><span class="n">key</span><span class="p">]</span> <span class="o">=</span> <span class="n">getvalue</span><span class="p">(</span><span class="n">key</span><span class="p">)</span>
|
||
</pre></div>
|
||
</div>
|
||
<p>For this specific case, you could also use <code class="docutils literal notranslate"><span class="pre">value</span> <span class="pre">=</span> <span class="pre">dict.setdefault(key,</span>
|
||
<span class="pre">getvalue(key))</span></code>, but only if the <code class="docutils literal notranslate"><span class="pre">getvalue()</span></code> call is cheap enough because it
|
||
is evaluated in all cases.</p>
|
||
</section>
|
||
<section id="why-isn-t-there-a-switch-or-case-statement-in-python">
|
||
<h2><a class="toc-backref" href="#id12" role="doc-backlink">Why isn’t there a switch or case statement in Python?</a><a class="headerlink" href="#why-isn-t-there-a-switch-or-case-statement-in-python" title="Link to this heading">¶</a></h2>
|
||
<p>In general, structured switch statements execute one block of code
|
||
when an expression has a particular value or set of values.
|
||
Since Python 3.10 one can easily match literal values, or constants
|
||
within a namespace, with a <code class="docutils literal notranslate"><span class="pre">match</span> <span class="pre">...</span> <span class="pre">case</span></code> statement.
|
||
An older alternative is a sequence of <code class="docutils literal notranslate"><span class="pre">if...</span> <span class="pre">elif...</span> <span class="pre">elif...</span> <span class="pre">else</span></code>.</p>
|
||
<p>For cases where you need to choose from a very large number of possibilities,
|
||
you can create a dictionary mapping case values to functions to call. For
|
||
example:</p>
|
||
<div class="highlight-python3 notranslate"><div class="highlight"><pre><span></span><span class="n">functions</span> <span class="o">=</span> <span class="p">{</span><span class="s1">'a'</span><span class="p">:</span> <span class="n">function_1</span><span class="p">,</span>
|
||
<span class="s1">'b'</span><span class="p">:</span> <span class="n">function_2</span><span class="p">,</span>
|
||
<span class="s1">'c'</span><span class="p">:</span> <span class="bp">self</span><span class="o">.</span><span class="n">method_1</span><span class="p">}</span>
|
||
|
||
<span class="n">func</span> <span class="o">=</span> <span class="n">functions</span><span class="p">[</span><span class="n">value</span><span class="p">]</span>
|
||
<span class="n">func</span><span class="p">()</span>
|
||
</pre></div>
|
||
</div>
|
||
<p>For calling methods on objects, you can simplify yet further by using the
|
||
<a class="reference internal" href="../library/functions.html#getattr" title="getattr"><code class="xref py py-func docutils literal notranslate"><span class="pre">getattr()</span></code></a> built-in to retrieve methods with a particular name:</p>
|
||
<div class="highlight-python3 notranslate"><div class="highlight"><pre><span></span><span class="k">class</span><span class="w"> </span><span class="nc">MyVisitor</span><span class="p">:</span>
|
||
<span class="k">def</span><span class="w"> </span><span class="nf">visit_a</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
|
||
<span class="o">...</span>
|
||
|
||
<span class="k">def</span><span class="w"> </span><span class="nf">dispatch</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">value</span><span class="p">):</span>
|
||
<span class="n">method_name</span> <span class="o">=</span> <span class="s1">'visit_'</span> <span class="o">+</span> <span class="nb">str</span><span class="p">(</span><span class="n">value</span><span class="p">)</span>
|
||
<span class="n">method</span> <span class="o">=</span> <span class="nb">getattr</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">method_name</span><span class="p">)</span>
|
||
<span class="n">method</span><span class="p">()</span>
|
||
</pre></div>
|
||
</div>
|
||
<p>It’s suggested that you use a prefix for the method names, such as <code class="docutils literal notranslate"><span class="pre">visit_</span></code> in
|
||
this example. Without such a prefix, if values are coming from an untrusted
|
||
source, an attacker would be able to call any method on your object.</p>
|
||
<p>Imitating switch with fallthrough, as with C’s switch-case-default,
|
||
is possible, much harder, and less needed.</p>
|
||
</section>
|
||
<section id="can-t-you-emulate-threads-in-the-interpreter-instead-of-relying-on-an-os-specific-thread-implementation">
|
||
<h2><a class="toc-backref" href="#id13" role="doc-backlink">Can’t you emulate threads in the interpreter instead of relying on an OS-specific thread implementation?</a><a class="headerlink" href="#can-t-you-emulate-threads-in-the-interpreter-instead-of-relying-on-an-os-specific-thread-implementation" title="Link to this heading">¶</a></h2>
|
||
<p>Answer 1: Unfortunately, the interpreter pushes at least one C stack frame for
|
||
each Python stack frame. Also, extensions can call back into Python at almost
|
||
random moments. Therefore, a complete threads implementation requires thread
|
||
support for C.</p>
|
||
<p>Answer 2: Fortunately, there is <a class="reference external" href="https://github.com/stackless-dev/stackless/wiki">Stackless Python</a>,
|
||
which has a completely redesigned interpreter loop that avoids the C stack.</p>
|
||
</section>
|
||
<section id="why-can-t-lambda-expressions-contain-statements">
|
||
<h2><a class="toc-backref" href="#id14" role="doc-backlink">Why can’t lambda expressions contain statements?</a><a class="headerlink" href="#why-can-t-lambda-expressions-contain-statements" title="Link to this heading">¶</a></h2>
|
||
<p>Python lambda expressions cannot contain statements because Python’s syntactic
|
||
framework can’t handle statements nested inside expressions. However, in
|
||
Python, this is not a serious problem. Unlike lambda forms in other languages,
|
||
where they add functionality, Python lambdas are only a shorthand notation if
|
||
you’re too lazy to define a function.</p>
|
||
<p>Functions are already first class objects in Python, and can be declared in a
|
||
local scope. Therefore the only advantage of using a lambda instead of a
|
||
locally defined function is that you don’t need to invent a name for the
|
||
function – but that’s just a local variable to which the function object (which
|
||
is exactly the same type of object that a lambda expression yields) is assigned!</p>
|
||
</section>
|
||
<section id="can-python-be-compiled-to-machine-code-c-or-some-other-language">
|
||
<h2><a class="toc-backref" href="#id15" role="doc-backlink">Can Python be compiled to machine code, C or some other language?</a><a class="headerlink" href="#can-python-be-compiled-to-machine-code-c-or-some-other-language" title="Link to this heading">¶</a></h2>
|
||
<p><a class="reference external" href="https://cython.org/">Cython</a> compiles a modified version of Python with
|
||
optional annotations into C extensions. <a class="reference external" href="https://nuitka.net/">Nuitka</a> is
|
||
an up-and-coming compiler of Python into C++ code, aiming to support the full
|
||
Python language.</p>
|
||
</section>
|
||
<section id="how-does-python-manage-memory">
|
||
<h2><a class="toc-backref" href="#id16" role="doc-backlink">How does Python manage memory?</a><a class="headerlink" href="#how-does-python-manage-memory" title="Link to this heading">¶</a></h2>
|
||
<p>The details of Python memory management depend on the implementation. The
|
||
standard implementation of Python, <a class="reference internal" href="../glossary.html#term-CPython"><span class="xref std std-term">CPython</span></a>, uses reference counting to
|
||
detect inaccessible objects, and another mechanism to collect reference cycles,
|
||
periodically executing a cycle detection algorithm which looks for inaccessible
|
||
cycles and deletes the objects involved. The <a class="reference internal" href="../library/gc.html#module-gc" title="gc: Interface to the cycle-detecting garbage collector."><code class="xref py py-mod docutils literal notranslate"><span class="pre">gc</span></code></a> module provides functions
|
||
to perform a garbage collection, obtain debugging statistics, and tune the
|
||
collector’s parameters.</p>
|
||
<p>Other implementations (such as <a class="reference external" href="https://www.jython.org">Jython</a> or
|
||
<a class="reference external" href="https://pypy.org">PyPy</a>), however, can rely on a different mechanism
|
||
such as a full-blown garbage collector. This difference can cause some
|
||
subtle porting problems if your Python code depends on the behavior of the
|
||
reference counting implementation.</p>
|
||
<p>In some Python implementations, the following code (which is fine in CPython)
|
||
will probably run out of file descriptors:</p>
|
||
<div class="highlight-python3 notranslate"><div class="highlight"><pre><span></span><span class="k">for</span> <span class="n">file</span> <span class="ow">in</span> <span class="n">very_long_list_of_files</span><span class="p">:</span>
|
||
<span class="n">f</span> <span class="o">=</span> <span class="nb">open</span><span class="p">(</span><span class="n">file</span><span class="p">)</span>
|
||
<span class="n">c</span> <span class="o">=</span> <span class="n">f</span><span class="o">.</span><span class="n">read</span><span class="p">(</span><span class="mi">1</span><span class="p">)</span>
|
||
</pre></div>
|
||
</div>
|
||
<p>Indeed, using CPython’s reference counting and destructor scheme, each new
|
||
assignment to <code class="docutils literal notranslate"><span class="pre">f</span></code> closes the previous file. With a traditional GC, however,
|
||
those file objects will only get collected (and closed) at varying and possibly
|
||
long intervals.</p>
|
||
<p>If you want to write code that will work with any Python implementation,
|
||
you should explicitly close the file or use the <a class="reference internal" href="../reference/compound_stmts.html#with"><code class="xref std std-keyword docutils literal notranslate"><span class="pre">with</span></code></a> statement;
|
||
this will work regardless of memory management scheme:</p>
|
||
<div class="highlight-python3 notranslate"><div class="highlight"><pre><span></span><span class="k">for</span> <span class="n">file</span> <span class="ow">in</span> <span class="n">very_long_list_of_files</span><span class="p">:</span>
|
||
<span class="k">with</span> <span class="nb">open</span><span class="p">(</span><span class="n">file</span><span class="p">)</span> <span class="k">as</span> <span class="n">f</span><span class="p">:</span>
|
||
<span class="n">c</span> <span class="o">=</span> <span class="n">f</span><span class="o">.</span><span class="n">read</span><span class="p">(</span><span class="mi">1</span><span class="p">)</span>
|
||
</pre></div>
|
||
</div>
|
||
</section>
|
||
<section id="why-doesn-t-cpython-use-a-more-traditional-garbage-collection-scheme">
|
||
<h2><a class="toc-backref" href="#id17" role="doc-backlink">Why doesn’t CPython use a more traditional garbage collection scheme?</a><a class="headerlink" href="#why-doesn-t-cpython-use-a-more-traditional-garbage-collection-scheme" title="Link to this heading">¶</a></h2>
|
||
<p>For one thing, this is not a C standard feature and hence it’s not portable.
|
||
(Yes, we know about the Boehm GC library. It has bits of assembler code for
|
||
<em>most</em> common platforms, not for all of them, and although it is mostly
|
||
transparent, it isn’t completely transparent; patches are required to get
|
||
Python to work with it.)</p>
|
||
<p>Traditional GC also becomes a problem when Python is embedded into other
|
||
applications. While in a standalone Python it’s fine to replace the standard
|
||
<code class="docutils literal notranslate"><span class="pre">malloc()</span></code> and <code class="docutils literal notranslate"><span class="pre">free()</span></code> with versions provided by the GC library, an application
|
||
embedding Python may want to have its <em>own</em> substitute for <code class="docutils literal notranslate"><span class="pre">malloc()</span></code> and <code class="docutils literal notranslate"><span class="pre">free()</span></code>,
|
||
and may not want Python’s. Right now, CPython works with anything that
|
||
implements <code class="docutils literal notranslate"><span class="pre">malloc()</span></code> and <code class="docutils literal notranslate"><span class="pre">free()</span></code> properly.</p>
|
||
</section>
|
||
<section id="why-isn-t-all-memory-freed-when-cpython-exits">
|
||
<h2><a class="toc-backref" href="#id18" role="doc-backlink">Why isn’t all memory freed when CPython exits?</a><a class="headerlink" href="#why-isn-t-all-memory-freed-when-cpython-exits" title="Link to this heading">¶</a></h2>
|
||
<p>Objects referenced from the global namespaces of Python modules are not always
|
||
deallocated when Python exits. This may happen if there are circular
|
||
references. There are also certain bits of memory that are allocated by the C
|
||
library that are impossible to free (e.g. a tool like Purify will complain about
|
||
these). Python is, however, aggressive about cleaning up memory on exit and
|
||
does try to destroy every single object.</p>
|
||
<p>If you want to force Python to delete certain things on deallocation use the
|
||
<a class="reference internal" href="../library/atexit.html#module-atexit" title="atexit: Register and execute cleanup functions."><code class="xref py py-mod docutils literal notranslate"><span class="pre">atexit</span></code></a> module to run a function that will force those deletions.</p>
|
||
</section>
|
||
<section id="why-are-there-separate-tuple-and-list-data-types">
|
||
<h2><a class="toc-backref" href="#id19" role="doc-backlink">Why are there separate tuple and list data types?</a><a class="headerlink" href="#why-are-there-separate-tuple-and-list-data-types" title="Link to this heading">¶</a></h2>
|
||
<p>Lists and tuples, while similar in many respects, are generally used in
|
||
fundamentally different ways. Tuples can be thought of as being similar to
|
||
Pascal <code class="docutils literal notranslate"><span class="pre">records</span></code> or C <code class="docutils literal notranslate"><span class="pre">structs</span></code>; they’re small collections of related data which may
|
||
be of different types which are operated on as a group. For example, a
|
||
Cartesian coordinate is appropriately represented as a tuple of two or three
|
||
numbers.</p>
|
||
<p>Lists, on the other hand, are more like arrays in other languages. They tend to
|
||
hold a varying number of objects all of which have the same type and which are
|
||
operated on one-by-one. For example, <a class="reference internal" href="../library/os.html#os.listdir" title="os.listdir"><code class="xref py py-func docutils literal notranslate"><span class="pre">os.listdir('.')</span></code></a>
|
||
returns a list of
|
||
strings representing the files in the current directory. Functions which
|
||
operate on this output would generally not break if you added another file or
|
||
two to the directory.</p>
|
||
<p>Tuples are immutable, meaning that once a tuple has been created, you can’t
|
||
replace any of its elements with a new value. Lists are mutable, meaning that
|
||
you can always change a list’s elements. Only immutable elements can be used as
|
||
dictionary keys, and hence only tuples and not lists can be used as keys.</p>
|
||
</section>
|
||
<section id="how-are-lists-implemented-in-cpython">
|
||
<h2><a class="toc-backref" href="#id20" role="doc-backlink">How are lists implemented in CPython?</a><a class="headerlink" href="#how-are-lists-implemented-in-cpython" title="Link to this heading">¶</a></h2>
|
||
<p>CPython’s lists are really variable-length arrays, not Lisp-style linked lists.
|
||
The implementation uses a contiguous array of references to other objects, and
|
||
keeps a pointer to this array and the array’s length in a list head structure.</p>
|
||
<p>This makes indexing a list <code class="docutils literal notranslate"><span class="pre">a[i]</span></code> an operation whose cost is independent of
|
||
the size of the list or the value of the index.</p>
|
||
<p>When items are appended or inserted, the array of references is resized. Some
|
||
cleverness is applied to improve the performance of appending items repeatedly;
|
||
when the array must be grown, some extra space is allocated so the next few
|
||
times don’t require an actual resize.</p>
|
||
</section>
|
||
<section id="how-are-dictionaries-implemented-in-cpython">
|
||
<h2><a class="toc-backref" href="#id21" role="doc-backlink">How are dictionaries implemented in CPython?</a><a class="headerlink" href="#how-are-dictionaries-implemented-in-cpython" title="Link to this heading">¶</a></h2>
|
||
<p>CPython’s dictionaries are implemented as resizable hash tables. Compared to
|
||
B-trees, this gives better performance for lookup (the most common operation by
|
||
far) under most circumstances, and the implementation is simpler.</p>
|
||
<p>Dictionaries work by computing a hash code for each key stored in the dictionary
|
||
using the <a class="reference internal" href="../library/functions.html#hash" title="hash"><code class="xref py py-func docutils literal notranslate"><span class="pre">hash()</span></code></a> built-in function. The hash code varies widely depending
|
||
on the key and a per-process seed; for example, <code class="docutils literal notranslate"><span class="pre">'Python'</span></code> could hash to
|
||
<code class="docutils literal notranslate"><span class="pre">-539294296</span></code> while <code class="docutils literal notranslate"><span class="pre">'python'</span></code>, a string that differs by a single bit, could hash
|
||
to <code class="docutils literal notranslate"><span class="pre">1142331976</span></code>. The hash code is then used to calculate a location in an
|
||
internal array where the value will be stored. Assuming that you’re storing
|
||
keys that all have different hash values, this means that dictionaries take
|
||
constant time – <em>O</em>(1), in Big-O notation – to retrieve a key.</p>
|
||
</section>
|
||
<section id="why-must-dictionary-keys-be-immutable">
|
||
<h2><a class="toc-backref" href="#id22" role="doc-backlink">Why must dictionary keys be immutable?</a><a class="headerlink" href="#why-must-dictionary-keys-be-immutable" title="Link to this heading">¶</a></h2>
|
||
<p>The hash table implementation of dictionaries uses a hash value calculated from
|
||
the key value to find the key. If the key were a mutable object, its value
|
||
could change, and thus its hash could also change. But since whoever changes
|
||
the key object can’t tell that it was being used as a dictionary key, it can’t
|
||
move the entry around in the dictionary. Then, when you try to look up the same
|
||
object in the dictionary it won’t be found because its hash value is different.
|
||
If you tried to look up the old value it wouldn’t be found either, because the
|
||
value of the object found in that hash bin would be different.</p>
|
||
<p>If you want a dictionary indexed with a list, simply convert the list to a tuple
|
||
first; the function <code class="docutils literal notranslate"><span class="pre">tuple(L)</span></code> creates a tuple with the same entries as the
|
||
list <code class="docutils literal notranslate"><span class="pre">L</span></code>. Tuples are immutable and can therefore be used as dictionary keys.</p>
|
||
<p>Some unacceptable solutions that have been proposed:</p>
|
||
<ul>
|
||
<li><p>Hash lists by their address (object ID). This doesn’t work because if you
|
||
construct a new list with the same value it won’t be found; e.g.:</p>
|
||
<div class="highlight-python3 notranslate"><div class="highlight"><pre><span></span><span class="n">mydict</span> <span class="o">=</span> <span class="p">{[</span><span class="mi">1</span><span class="p">,</span> <span class="mi">2</span><span class="p">]:</span> <span class="s1">'12'</span><span class="p">}</span>
|
||
<span class="nb">print</span><span class="p">(</span><span class="n">mydict</span><span class="p">[[</span><span class="mi">1</span><span class="p">,</span> <span class="mi">2</span><span class="p">]])</span>
|
||
</pre></div>
|
||
</div>
|
||
<p>would raise a <a class="reference internal" href="../library/exceptions.html#KeyError" title="KeyError"><code class="xref py py-exc docutils literal notranslate"><span class="pre">KeyError</span></code></a> exception because the id of the <code class="docutils literal notranslate"><span class="pre">[1,</span> <span class="pre">2]</span></code> used in the
|
||
second line differs from that in the first line. In other words, dictionary
|
||
keys should be compared using <code class="docutils literal notranslate"><span class="pre">==</span></code>, not using <a class="reference internal" href="../reference/expressions.html#is"><code class="xref std std-keyword docutils literal notranslate"><span class="pre">is</span></code></a>.</p>
|
||
</li>
|
||
<li><p>Make a copy when using a list as a key. This doesn’t work because the list,
|
||
being a mutable object, could contain a reference to itself, and then the
|
||
copying code would run into an infinite loop.</p></li>
|
||
<li><p>Allow lists as keys but tell the user not to modify them. This would allow a
|
||
class of hard-to-track bugs in programs when you forgot or modified a list by
|
||
accident. It also invalidates an important invariant of dictionaries: every
|
||
value in <code class="docutils literal notranslate"><span class="pre">d.keys()</span></code> is usable as a key of the dictionary.</p></li>
|
||
<li><p>Mark lists as read-only once they are used as a dictionary key. The problem
|
||
is that it’s not just the top-level object that could change its value; you
|
||
could use a tuple containing a list as a key. Entering anything as a key into
|
||
a dictionary would require marking all objects reachable from there as
|
||
read-only – and again, self-referential objects could cause an infinite loop.</p></li>
|
||
</ul>
|
||
<p>There is a trick to get around this if you need to, but use it at your own risk:
|
||
You can wrap a mutable structure inside a class instance which has both a
|
||
<a class="reference internal" href="../reference/datamodel.html#object.__eq__" title="object.__eq__"><code class="xref py py-meth docutils literal notranslate"><span class="pre">__eq__()</span></code></a> and a <a class="reference internal" href="../reference/datamodel.html#object.__hash__" title="object.__hash__"><code class="xref py py-meth docutils literal notranslate"><span class="pre">__hash__()</span></code></a> method.
|
||
You must then make sure that the
|
||
hash value for all such wrapper objects that reside in a dictionary (or other
|
||
hash based structure), remain fixed while the object is in the dictionary (or
|
||
other structure).</p>
|
||
<div class="highlight-python3 notranslate"><div class="highlight"><pre><span></span><span class="k">class</span><span class="w"> </span><span class="nc">ListWrapper</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">the_list</span><span class="p">):</span>
|
||
<span class="bp">self</span><span class="o">.</span><span class="n">the_list</span> <span class="o">=</span> <span class="n">the_list</span>
|
||
|
||
<span class="k">def</span><span class="w"> </span><span class="fm">__eq__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">other</span><span class="p">):</span>
|
||
<span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">the_list</span> <span class="o">==</span> <span class="n">other</span><span class="o">.</span><span class="n">the_list</span>
|
||
|
||
<span class="k">def</span><span class="w"> </span><span class="fm">__hash__</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
|
||
<span class="n">l</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">the_list</span>
|
||
<span class="n">result</span> <span class="o">=</span> <span class="mi">98767</span> <span class="o">-</span> <span class="nb">len</span><span class="p">(</span><span class="n">l</span><span class="p">)</span><span class="o">*</span><span class="mi">555</span>
|
||
<span class="k">for</span> <span class="n">i</span><span class="p">,</span> <span class="n">el</span> <span class="ow">in</span> <span class="nb">enumerate</span><span class="p">(</span><span class="n">l</span><span class="p">):</span>
|
||
<span class="k">try</span><span class="p">:</span>
|
||
<span class="n">result</span> <span class="o">=</span> <span class="n">result</span> <span class="o">+</span> <span class="p">(</span><span class="nb">hash</span><span class="p">(</span><span class="n">el</span><span class="p">)</span> <span class="o">%</span> <span class="mi">9999999</span><span class="p">)</span> <span class="o">*</span> <span class="mi">1001</span> <span class="o">+</span> <span class="n">i</span>
|
||
<span class="k">except</span> <span class="ne">Exception</span><span class="p">:</span>
|
||
<span class="n">result</span> <span class="o">=</span> <span class="p">(</span><span class="n">result</span> <span class="o">%</span> <span class="mi">7777777</span><span class="p">)</span> <span class="o">+</span> <span class="n">i</span> <span class="o">*</span> <span class="mi">333</span>
|
||
<span class="k">return</span> <span class="n">result</span>
|
||
</pre></div>
|
||
</div>
|
||
<p>Note that the hash computation is complicated by the possibility that some
|
||
members of the list may be unhashable and also by the possibility of arithmetic
|
||
overflow.</p>
|
||
<p>Furthermore it must always be the case that if <code class="docutils literal notranslate"><span class="pre">o1</span> <span class="pre">==</span> <span class="pre">o2</span></code> (ie <code class="docutils literal notranslate"><span class="pre">o1.__eq__(o2)</span>
|
||
<span class="pre">is</span> <span class="pre">True</span></code>) then <code class="docutils literal notranslate"><span class="pre">hash(o1)</span> <span class="pre">==</span> <span class="pre">hash(o2)</span></code> (ie, <code class="docutils literal notranslate"><span class="pre">o1.__hash__()</span> <span class="pre">==</span> <span class="pre">o2.__hash__()</span></code>),
|
||
regardless of whether the object is in a dictionary or not. If you fail to meet
|
||
these restrictions dictionaries and other hash based structures will misbehave.</p>
|
||
<p>In the case of <code class="xref py py-class docutils literal notranslate"><span class="pre">ListWrapper</span></code>, whenever the wrapper object is in a dictionary the
|
||
wrapped list must not change to avoid anomalies. Don’t do this unless you are
|
||
prepared to think hard about the requirements and the consequences of not
|
||
meeting them correctly. Consider yourself warned.</p>
|
||
</section>
|
||
<section id="why-doesn-t-list-sort-return-the-sorted-list">
|
||
<h2><a class="toc-backref" href="#id23" role="doc-backlink">Why doesn’t list.sort() return the sorted list?</a><a class="headerlink" href="#why-doesn-t-list-sort-return-the-sorted-list" title="Link to this heading">¶</a></h2>
|
||
<p>In situations where performance matters, making a copy of the list just to sort
|
||
it would be wasteful. Therefore, <a class="reference internal" href="../library/stdtypes.html#list.sort" title="list.sort"><code class="xref py py-meth docutils literal notranslate"><span class="pre">list.sort()</span></code></a> sorts the list in place. In
|
||
order to remind you of that fact, it does not return the sorted list. This way,
|
||
you won’t be fooled into accidentally overwriting a list when you need a sorted
|
||
copy but also need to keep the unsorted version around.</p>
|
||
<p>If you want to return a new list, use the built-in <a class="reference internal" href="../library/functions.html#sorted" title="sorted"><code class="xref py py-func docutils literal notranslate"><span class="pre">sorted()</span></code></a> function
|
||
instead. This function creates a new list from a provided iterable, sorts
|
||
it and returns it. For example, here’s how to iterate over the keys of a
|
||
dictionary in sorted order:</p>
|
||
<div class="highlight-python3 notranslate"><div class="highlight"><pre><span></span><span class="k">for</span> <span class="n">key</span> <span class="ow">in</span> <span class="nb">sorted</span><span class="p">(</span><span class="n">mydict</span><span class="p">):</span>
|
||
<span class="o">...</span> <span class="c1"># do whatever with mydict[key]...</span>
|
||
</pre></div>
|
||
</div>
|
||
</section>
|
||
<section id="how-do-you-specify-and-enforce-an-interface-spec-in-python">
|
||
<h2><a class="toc-backref" href="#id24" role="doc-backlink">How do you specify and enforce an interface spec in Python?</a><a class="headerlink" href="#how-do-you-specify-and-enforce-an-interface-spec-in-python" title="Link to this heading">¶</a></h2>
|
||
<p>An interface specification for a module as provided by languages such as C++ and
|
||
Java describes the prototypes for the methods and functions of the module. Many
|
||
feel that compile-time enforcement of interface specifications helps in the
|
||
construction of large programs.</p>
|
||
<p>Python 2.6 adds an <a class="reference internal" href="../library/abc.html#module-abc" title="abc: Abstract base classes according to :pep:`3119`."><code class="xref py py-mod docutils literal notranslate"><span class="pre">abc</span></code></a> module that lets you define Abstract Base Classes
|
||
(ABCs). You can then use <a class="reference internal" href="../library/functions.html#isinstance" title="isinstance"><code class="xref py py-func docutils literal notranslate"><span class="pre">isinstance()</span></code></a> and <a class="reference internal" href="../library/functions.html#issubclass" title="issubclass"><code class="xref py py-func docutils literal notranslate"><span class="pre">issubclass()</span></code></a> to check
|
||
whether an instance or a class implements a particular ABC. The
|
||
<a class="reference internal" href="../library/collections.abc.html#module-collections.abc" title="collections.abc: Abstract base classes for containers"><code class="xref py py-mod docutils literal notranslate"><span class="pre">collections.abc</span></code></a> module defines a set of useful ABCs such as
|
||
<a class="reference internal" href="../library/collections.abc.html#collections.abc.Iterable" title="collections.abc.Iterable"><code class="xref py py-class docutils literal notranslate"><span class="pre">Iterable</span></code></a>, <a class="reference internal" href="../library/collections.abc.html#collections.abc.Container" title="collections.abc.Container"><code class="xref py py-class docutils literal notranslate"><span class="pre">Container</span></code></a>, and
|
||
<a class="reference internal" href="../library/collections.abc.html#collections.abc.MutableMapping" title="collections.abc.MutableMapping"><code class="xref py py-class docutils literal notranslate"><span class="pre">MutableMapping</span></code></a>.</p>
|
||
<p>For Python, many of the advantages of interface specifications can be obtained
|
||
by an appropriate test discipline for components.</p>
|
||
<p>A good test suite for a module can both provide a regression test and serve as a
|
||
module interface specification and a set of examples. Many Python modules can
|
||
be run as a script to provide a simple “self test.” Even modules which use
|
||
complex external interfaces can often be tested in isolation using trivial
|
||
“stub” emulations of the external interface. The <a class="reference internal" href="../library/doctest.html#module-doctest" title="doctest: Test pieces of code within docstrings."><code class="xref py py-mod docutils literal notranslate"><span class="pre">doctest</span></code></a> and
|
||
<a class="reference internal" href="../library/unittest.html#module-unittest" title="unittest: Unit testing framework for Python."><code class="xref py py-mod docutils literal notranslate"><span class="pre">unittest</span></code></a> modules or third-party test frameworks can be used to construct
|
||
exhaustive test suites that exercise every line of code in a module.</p>
|
||
<p>An appropriate testing discipline can help build large complex applications in
|
||
Python as well as having interface specifications would. In fact, it can be
|
||
better because an interface specification cannot test certain properties of a
|
||
program. For example, the <code class="xref py py-meth docutils literal notranslate"><span class="pre">list.append()</span></code> method is expected to add new elements
|
||
to the end of some internal list; an interface specification cannot test that
|
||
your <code class="xref py py-meth docutils literal notranslate"><span class="pre">list.append()</span></code> implementation will actually do this correctly, but it’s
|
||
trivial to check this property in a test suite.</p>
|
||
<p>Writing test suites is very helpful, and you might want to design your code to
|
||
make it easily tested. One increasingly popular technique, test-driven
|
||
development, calls for writing parts of the test suite first, before you write
|
||
any of the actual code. Of course Python allows you to be sloppy and not write
|
||
test cases at all.</p>
|
||
</section>
|
||
<section id="why-is-there-no-goto">
|
||
<h2><a class="toc-backref" href="#id25" role="doc-backlink">Why is there no goto?</a><a class="headerlink" href="#why-is-there-no-goto" title="Link to this heading">¶</a></h2>
|
||
<p>In the 1970s people realized that unrestricted goto could lead
|
||
to messy “spaghetti” code that was hard to understand and revise.
|
||
In a high-level language, it is also unneeded as long as there
|
||
are ways to branch (in Python, with <a class="reference internal" href="../reference/compound_stmts.html#if"><code class="xref std std-keyword docutils literal notranslate"><span class="pre">if</span></code></a> statements and <a class="reference internal" href="../reference/expressions.html#or"><code class="xref std std-keyword docutils literal notranslate"><span class="pre">or</span></code></a>,
|
||
<a class="reference internal" href="../reference/expressions.html#and"><code class="xref std std-keyword docutils literal notranslate"><span class="pre">and</span></code></a>, and <a class="reference internal" href="../reference/compound_stmts.html#if"><code class="xref std std-keyword docutils literal notranslate"><span class="pre">if</span></code></a>/<a class="reference internal" href="../reference/compound_stmts.html#else"><code class="xref std std-keyword docutils literal notranslate"><span class="pre">else</span></code></a> expressions) and loop (with <a class="reference internal" href="../reference/compound_stmts.html#while"><code class="xref std std-keyword docutils literal notranslate"><span class="pre">while</span></code></a>
|
||
and <a class="reference internal" href="../reference/compound_stmts.html#for"><code class="xref std std-keyword docutils literal notranslate"><span class="pre">for</span></code></a> statements, possibly containing <a class="reference internal" href="../reference/simple_stmts.html#continue"><code class="xref std std-keyword docutils literal notranslate"><span class="pre">continue</span></code></a> and <a class="reference internal" href="../reference/simple_stmts.html#break"><code class="xref std std-keyword docutils literal notranslate"><span class="pre">break</span></code></a>).</p>
|
||
<p>One can also use exceptions to provide a “structured goto”
|
||
that works even across
|
||
function calls. Many feel that exceptions can conveniently emulate all
|
||
reasonable uses of the <code class="docutils literal notranslate"><span class="pre">go</span></code> or <code class="docutils literal notranslate"><span class="pre">goto</span></code> constructs of C, Fortran, and other
|
||
languages. For example:</p>
|
||
<div class="highlight-python3 notranslate"><div class="highlight"><pre><span></span><span class="k">class</span><span class="w"> </span><span class="nc">label</span><span class="p">(</span><span class="ne">Exception</span><span class="p">):</span> <span class="k">pass</span> <span class="c1"># declare a label</span>
|
||
|
||
<span class="k">try</span><span class="p">:</span>
|
||
<span class="o">...</span>
|
||
<span class="k">if</span> <span class="n">condition</span><span class="p">:</span> <span class="k">raise</span> <span class="n">label</span><span class="p">()</span> <span class="c1"># goto label</span>
|
||
<span class="o">...</span>
|
||
<span class="k">except</span> <span class="n">label</span><span class="p">:</span> <span class="c1"># where to goto</span>
|
||
<span class="k">pass</span>
|
||
<span class="o">...</span>
|
||
</pre></div>
|
||
</div>
|
||
<p>This doesn’t allow you to jump into the middle of a loop, but that’s usually
|
||
considered an abuse of <code class="docutils literal notranslate"><span class="pre">goto</span></code> anyway. Use sparingly.</p>
|
||
</section>
|
||
<section id="why-can-t-raw-strings-r-strings-end-with-a-backslash">
|
||
<h2><a class="toc-backref" href="#id26" role="doc-backlink">Why can’t raw strings (r-strings) end with a backslash?</a><a class="headerlink" href="#why-can-t-raw-strings-r-strings-end-with-a-backslash" title="Link to this heading">¶</a></h2>
|
||
<p>More precisely, they can’t end with an odd number of backslashes: the unpaired
|
||
backslash at the end escapes the closing quote character, leaving an
|
||
unterminated string.</p>
|
||
<p>Raw strings were designed to ease creating input for processors (chiefly regular
|
||
expression engines) that want to do their own backslash escape processing. Such
|
||
processors consider an unmatched trailing backslash to be an error anyway, so
|
||
raw strings disallow that. In return, they allow you to pass on the string
|
||
quote character by escaping it with a backslash. These rules work well when
|
||
r-strings are used for their intended purpose.</p>
|
||
<p>If you’re trying to build Windows pathnames, note that all Windows system calls
|
||
accept forward slashes too:</p>
|
||
<div class="highlight-python3 notranslate"><div class="highlight"><pre><span></span><span class="n">f</span> <span class="o">=</span> <span class="nb">open</span><span class="p">(</span><span class="s2">"/mydir/file.txt"</span><span class="p">)</span> <span class="c1"># works fine!</span>
|
||
</pre></div>
|
||
</div>
|
||
<p>If you’re trying to build a pathname for a DOS command, try e.g. one of</p>
|
||
<div class="highlight-python3 notranslate"><div class="highlight"><pre><span></span><span class="nb">dir</span> <span class="o">=</span> <span class="sa">r</span><span class="s2">"\this\is\my\dos\dir"</span> <span class="s2">"</span><span class="se">\\</span><span class="s2">"</span>
|
||
<span class="nb">dir</span> <span class="o">=</span> <span class="sa">r</span><span class="s2">"\this\is\my\dos\dir\ "</span><span class="p">[:</span><span class="o">-</span><span class="mi">1</span><span class="p">]</span>
|
||
<span class="nb">dir</span> <span class="o">=</span> <span class="s2">"</span><span class="se">\\</span><span class="s2">this</span><span class="se">\\</span><span class="s2">is</span><span class="se">\\</span><span class="s2">my</span><span class="se">\\</span><span class="s2">dos</span><span class="se">\\</span><span class="s2">dir</span><span class="se">\\</span><span class="s2">"</span>
|
||
</pre></div>
|
||
</div>
|
||
</section>
|
||
<section id="why-doesn-t-python-have-a-with-statement-for-attribute-assignments">
|
||
<h2><a class="toc-backref" href="#id27" role="doc-backlink">Why doesn’t Python have a “with” statement for attribute assignments?</a><a class="headerlink" href="#why-doesn-t-python-have-a-with-statement-for-attribute-assignments" title="Link to this heading">¶</a></h2>
|
||
<p>Python has a <a class="reference internal" href="../reference/compound_stmts.html#with"><code class="xref std std-keyword docutils literal notranslate"><span class="pre">with</span></code></a> statement that wraps the execution of a block, calling code
|
||
on the entrance and exit from the block. Some languages have a construct that
|
||
looks like this:</p>
|
||
<div class="highlight-python3 notranslate"><div class="highlight"><pre><span></span><span class="k">with</span> <span class="n">obj</span><span class="p">:</span>
|
||
<span class="n">a</span> <span class="o">=</span> <span class="mi">1</span> <span class="c1"># equivalent to obj.a = 1</span>
|
||
<span class="n">total</span> <span class="o">=</span> <span class="n">total</span> <span class="o">+</span> <span class="mi">1</span> <span class="c1"># obj.total = obj.total + 1</span>
|
||
</pre></div>
|
||
</div>
|
||
<p>In Python, such a construct would be ambiguous.</p>
|
||
<p>Other languages, such as Object Pascal, Delphi, and C++, use static types, so
|
||
it’s possible to know, in an unambiguous way, what member is being assigned
|
||
to. This is the main point of static typing – the compiler <em>always</em> knows the
|
||
scope of every variable at compile time.</p>
|
||
<p>Python uses dynamic types. It is impossible to know in advance which attribute
|
||
will be referenced at runtime. Member attributes may be added or removed from
|
||
objects on the fly. This makes it impossible to know, from a simple reading,
|
||
what attribute is being referenced: a local one, a global one, or a member
|
||
attribute?</p>
|
||
<p>For instance, take the following incomplete snippet:</p>
|
||
<div class="highlight-python3 notranslate"><div class="highlight"><pre><span></span><span class="k">def</span><span class="w"> </span><span class="nf">foo</span><span class="p">(</span><span class="n">a</span><span class="p">):</span>
|
||
<span class="k">with</span> <span class="n">a</span><span class="p">:</span>
|
||
<span class="nb">print</span><span class="p">(</span><span class="n">x</span><span class="p">)</span>
|
||
</pre></div>
|
||
</div>
|
||
<p>The snippet assumes that <code class="docutils literal notranslate"><span class="pre">a</span></code> must have a member attribute called <code class="docutils literal notranslate"><span class="pre">x</span></code>. However,
|
||
there is nothing in Python that tells the interpreter this. What should happen
|
||
if <code class="docutils literal notranslate"><span class="pre">a</span></code> is, let us say, an integer? If there is a global variable named <code class="docutils literal notranslate"><span class="pre">x</span></code>,
|
||
will it be used inside the <a class="reference internal" href="../reference/compound_stmts.html#with"><code class="xref std std-keyword docutils literal notranslate"><span class="pre">with</span></code></a> block? As you see, the dynamic nature of Python
|
||
makes such choices much harder.</p>
|
||
<p>The primary benefit of <a class="reference internal" href="../reference/compound_stmts.html#with"><code class="xref std std-keyword docutils literal notranslate"><span class="pre">with</span></code></a> and similar language features (reduction of code
|
||
volume) can, however, easily be achieved in Python by assignment. Instead of:</p>
|
||
<div class="highlight-python3 notranslate"><div class="highlight"><pre><span></span><span class="n">function</span><span class="p">(</span><span class="n">args</span><span class="p">)</span><span class="o">.</span><span class="n">mydict</span><span class="p">[</span><span class="n">index</span><span class="p">][</span><span class="n">index</span><span class="p">]</span><span class="o">.</span><span class="n">a</span> <span class="o">=</span> <span class="mi">21</span>
|
||
<span class="n">function</span><span class="p">(</span><span class="n">args</span><span class="p">)</span><span class="o">.</span><span class="n">mydict</span><span class="p">[</span><span class="n">index</span><span class="p">][</span><span class="n">index</span><span class="p">]</span><span class="o">.</span><span class="n">b</span> <span class="o">=</span> <span class="mi">42</span>
|
||
<span class="n">function</span><span class="p">(</span><span class="n">args</span><span class="p">)</span><span class="o">.</span><span class="n">mydict</span><span class="p">[</span><span class="n">index</span><span class="p">][</span><span class="n">index</span><span class="p">]</span><span class="o">.</span><span class="n">c</span> <span class="o">=</span> <span class="mi">63</span>
|
||
</pre></div>
|
||
</div>
|
||
<p>write this:</p>
|
||
<div class="highlight-python3 notranslate"><div class="highlight"><pre><span></span><span class="n">ref</span> <span class="o">=</span> <span class="n">function</span><span class="p">(</span><span class="n">args</span><span class="p">)</span><span class="o">.</span><span class="n">mydict</span><span class="p">[</span><span class="n">index</span><span class="p">][</span><span class="n">index</span><span class="p">]</span>
|
||
<span class="n">ref</span><span class="o">.</span><span class="n">a</span> <span class="o">=</span> <span class="mi">21</span>
|
||
<span class="n">ref</span><span class="o">.</span><span class="n">b</span> <span class="o">=</span> <span class="mi">42</span>
|
||
<span class="n">ref</span><span class="o">.</span><span class="n">c</span> <span class="o">=</span> <span class="mi">63</span>
|
||
</pre></div>
|
||
</div>
|
||
<p>This also has the side-effect of increasing execution speed because name
|
||
bindings are resolved at run-time in Python, and the second version only needs
|
||
to perform the resolution once.</p>
|
||
<p>Similar proposals that would introduce syntax to further reduce code volume,
|
||
such as using a ‘leading dot’, have been rejected in favour of explicitness (see
|
||
<a class="reference external" href="https://mail.python.org/pipermail/python-ideas/2016-May/040070.html">https://mail.python.org/pipermail/python-ideas/2016-May/040070.html</a>).</p>
|
||
</section>
|
||
<section id="why-don-t-generators-support-the-with-statement">
|
||
<h2><a class="toc-backref" href="#id28" role="doc-backlink">Why don’t generators support the with statement?</a><a class="headerlink" href="#why-don-t-generators-support-the-with-statement" title="Link to this heading">¶</a></h2>
|
||
<p>For technical reasons, a generator used directly as a context manager
|
||
would not work correctly. When, as is most common, a generator is used as
|
||
an iterator run to completion, no closing is needed. When it is, wrap
|
||
it as <a class="reference internal" href="../library/contextlib.html#contextlib.closing" title="contextlib.closing"><code class="xref py py-func docutils literal notranslate"><span class="pre">contextlib.closing(generator)</span></code></a>
|
||
in the <a class="reference internal" href="../reference/compound_stmts.html#with"><code class="xref std std-keyword docutils literal notranslate"><span class="pre">with</span></code></a> statement.</p>
|
||
</section>
|
||
<section id="why-are-colons-required-for-the-if-while-def-class-statements">
|
||
<h2><a class="toc-backref" href="#id29" role="doc-backlink">Why are colons required for the if/while/def/class statements?</a><a class="headerlink" href="#why-are-colons-required-for-the-if-while-def-class-statements" title="Link to this heading">¶</a></h2>
|
||
<p>The colon is required primarily to enhance readability (one of the results of
|
||
the experimental ABC language). Consider this:</p>
|
||
<div class="highlight-python3 notranslate"><div class="highlight"><pre><span></span><span class="k">if</span> <span class="n">a</span> <span class="o">==</span> <span class="n">b</span>
|
||
<span class="nb">print</span><span class="p">(</span><span class="n">a</span><span class="p">)</span>
|
||
</pre></div>
|
||
</div>
|
||
<p>versus</p>
|
||
<div class="highlight-python3 notranslate"><div class="highlight"><pre><span></span><span class="k">if</span> <span class="n">a</span> <span class="o">==</span> <span class="n">b</span><span class="p">:</span>
|
||
<span class="nb">print</span><span class="p">(</span><span class="n">a</span><span class="p">)</span>
|
||
</pre></div>
|
||
</div>
|
||
<p>Notice how the second one is slightly easier to read. Notice further how a
|
||
colon sets off the example in this FAQ answer; it’s a standard usage in English.</p>
|
||
<p>Another minor reason is that the colon makes it easier for editors with syntax
|
||
highlighting; they can look for colons to decide when indentation needs to be
|
||
increased instead of having to do a more elaborate parsing of the program text.</p>
|
||
</section>
|
||
<section id="why-does-python-allow-commas-at-the-end-of-lists-and-tuples">
|
||
<h2><a class="toc-backref" href="#id30" role="doc-backlink">Why does Python allow commas at the end of lists and tuples?</a><a class="headerlink" href="#why-does-python-allow-commas-at-the-end-of-lists-and-tuples" title="Link to this heading">¶</a></h2>
|
||
<p>Python lets you add a trailing comma at the end of lists, tuples, and
|
||
dictionaries:</p>
|
||
<div class="highlight-python3 notranslate"><div class="highlight"><pre><span></span><span class="p">[</span><span class="mi">1</span><span class="p">,</span> <span class="mi">2</span><span class="p">,</span> <span class="mi">3</span><span class="p">,]</span>
|
||
<span class="p">(</span><span class="s1">'a'</span><span class="p">,</span> <span class="s1">'b'</span><span class="p">,</span> <span class="s1">'c'</span><span class="p">,)</span>
|
||
<span class="n">d</span> <span class="o">=</span> <span class="p">{</span>
|
||
<span class="s2">"A"</span><span class="p">:</span> <span class="p">[</span><span class="mi">1</span><span class="p">,</span> <span class="mi">5</span><span class="p">],</span>
|
||
<span class="s2">"B"</span><span class="p">:</span> <span class="p">[</span><span class="mi">6</span><span class="p">,</span> <span class="mi">7</span><span class="p">],</span> <span class="c1"># last trailing comma is optional but good style</span>
|
||
<span class="p">}</span>
|
||
</pre></div>
|
||
</div>
|
||
<p>There are several reasons to allow this.</p>
|
||
<p>When you have a literal value for a list, tuple, or dictionary spread across
|
||
multiple lines, it’s easier to add more elements because you don’t have to
|
||
remember to add a comma to the previous line. The lines can also be reordered
|
||
without creating a syntax error.</p>
|
||
<p>Accidentally omitting the comma can lead to errors that are hard to diagnose.
|
||
For example:</p>
|
||
<div class="highlight-python3 notranslate"><div class="highlight"><pre><span></span><span class="n">x</span> <span class="o">=</span> <span class="p">[</span>
|
||
<span class="s2">"fee"</span><span class="p">,</span>
|
||
<span class="s2">"fie"</span>
|
||
<span class="s2">"foo"</span><span class="p">,</span>
|
||
<span class="s2">"fum"</span>
|
||
<span class="p">]</span>
|
||
</pre></div>
|
||
</div>
|
||
<p>This list looks like it has four elements, but it actually contains three:
|
||
“fee”, “fiefoo” and “fum”. Always adding the comma avoids this source of error.</p>
|
||
<p>Allowing the trailing comma may also make programmatic code generation easier.</p>
|
||
</section>
|
||
</section>
|
||
|
||
|
||
<div class="clearer"></div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<div class="sphinxsidebar" role="navigation" aria-label="Main">
|
||
<div class="sphinxsidebarwrapper">
|
||
<div>
|
||
<h3><a href="../contents.html">Table of Contents</a></h3>
|
||
<ul>
|
||
<li><a class="reference internal" href="#">Design and History FAQ</a><ul>
|
||
<li><a class="reference internal" href="#why-does-python-use-indentation-for-grouping-of-statements">Why does Python use indentation for grouping of statements?</a></li>
|
||
<li><a class="reference internal" href="#why-am-i-getting-strange-results-with-simple-arithmetic-operations">Why am I getting strange results with simple arithmetic operations?</a></li>
|
||
<li><a class="reference internal" href="#why-are-floating-point-calculations-so-inaccurate">Why are floating-point calculations so inaccurate?</a></li>
|
||
<li><a class="reference internal" href="#why-are-python-strings-immutable">Why are Python strings immutable?</a></li>
|
||
<li><a class="reference internal" href="#why-must-self-be-used-explicitly-in-method-definitions-and-calls">Why must ‘self’ be used explicitly in method definitions and calls?</a></li>
|
||
<li><a class="reference internal" href="#why-can-t-i-use-an-assignment-in-an-expression">Why can’t I use an assignment in an expression?</a></li>
|
||
<li><a class="reference internal" href="#why-does-python-use-methods-for-some-functionality-e-g-list-index-but-functions-for-other-e-g-len-list">Why does Python use methods for some functionality (e.g. list.index()) but functions for other (e.g. len(list))?</a></li>
|
||
<li><a class="reference internal" href="#why-is-join-a-string-method-instead-of-a-list-or-tuple-method">Why is join() a string method instead of a list or tuple method?</a></li>
|
||
<li><a class="reference internal" href="#how-fast-are-exceptions">How fast are exceptions?</a></li>
|
||
<li><a class="reference internal" href="#why-isn-t-there-a-switch-or-case-statement-in-python">Why isn’t there a switch or case statement in Python?</a></li>
|
||
<li><a class="reference internal" href="#can-t-you-emulate-threads-in-the-interpreter-instead-of-relying-on-an-os-specific-thread-implementation">Can’t you emulate threads in the interpreter instead of relying on an OS-specific thread implementation?</a></li>
|
||
<li><a class="reference internal" href="#why-can-t-lambda-expressions-contain-statements">Why can’t lambda expressions contain statements?</a></li>
|
||
<li><a class="reference internal" href="#can-python-be-compiled-to-machine-code-c-or-some-other-language">Can Python be compiled to machine code, C or some other language?</a></li>
|
||
<li><a class="reference internal" href="#how-does-python-manage-memory">How does Python manage memory?</a></li>
|
||
<li><a class="reference internal" href="#why-doesn-t-cpython-use-a-more-traditional-garbage-collection-scheme">Why doesn’t CPython use a more traditional garbage collection scheme?</a></li>
|
||
<li><a class="reference internal" href="#why-isn-t-all-memory-freed-when-cpython-exits">Why isn’t all memory freed when CPython exits?</a></li>
|
||
<li><a class="reference internal" href="#why-are-there-separate-tuple-and-list-data-types">Why are there separate tuple and list data types?</a></li>
|
||
<li><a class="reference internal" href="#how-are-lists-implemented-in-cpython">How are lists implemented in CPython?</a></li>
|
||
<li><a class="reference internal" href="#how-are-dictionaries-implemented-in-cpython">How are dictionaries implemented in CPython?</a></li>
|
||
<li><a class="reference internal" href="#why-must-dictionary-keys-be-immutable">Why must dictionary keys be immutable?</a></li>
|
||
<li><a class="reference internal" href="#why-doesn-t-list-sort-return-the-sorted-list">Why doesn’t list.sort() return the sorted list?</a></li>
|
||
<li><a class="reference internal" href="#how-do-you-specify-and-enforce-an-interface-spec-in-python">How do you specify and enforce an interface spec in Python?</a></li>
|
||
<li><a class="reference internal" href="#why-is-there-no-goto">Why is there no goto?</a></li>
|
||
<li><a class="reference internal" href="#why-can-t-raw-strings-r-strings-end-with-a-backslash">Why can’t raw strings (r-strings) end with a backslash?</a></li>
|
||
<li><a class="reference internal" href="#why-doesn-t-python-have-a-with-statement-for-attribute-assignments">Why doesn’t Python have a “with” statement for attribute assignments?</a></li>
|
||
<li><a class="reference internal" href="#why-don-t-generators-support-the-with-statement">Why don’t generators support the with statement?</a></li>
|
||
<li><a class="reference internal" href="#why-are-colons-required-for-the-if-while-def-class-statements">Why are colons required for the if/while/def/class statements?</a></li>
|
||
<li><a class="reference internal" href="#why-does-python-allow-commas-at-the-end-of-lists-and-tuples">Why does Python allow commas at the end of lists and tuples?</a></li>
|
||
</ul>
|
||
</li>
|
||
</ul>
|
||
|
||
</div>
|
||
<div>
|
||
<h4>Previous topic</h4>
|
||
<p class="topless"><a href="programming.html"
|
||
title="previous chapter">Programming FAQ</a></p>
|
||
</div>
|
||
<div>
|
||
<h4>Next topic</h4>
|
||
<p class="topless"><a href="library.html"
|
||
title="next chapter">Library and Extension FAQ</a></p>
|
||
</div>
|
||
<div role="note" aria-label="source link">
|
||
<h3>This Page</h3>
|
||
<ul class="this-page-menu">
|
||
<li><a href="../bugs.html">Report a Bug</a></li>
|
||
<li>
|
||
<a href="https://github.com/python/cpython/blob/main/Doc/faq/design.rst"
|
||
rel="nofollow">Show Source
|
||
</a>
|
||
</li>
|
||
</ul>
|
||
</div>
|
||
</div>
|
||
<div id="sidebarbutton" title="Collapse sidebar">
|
||
<span>«</span>
|
||
</div>
|
||
|
||
</div>
|
||
<div class="clearer"></div>
|
||
</div>
|
||
<div class="related" role="navigation" aria-label="Related">
|
||
<h3>Navigation</h3>
|
||
<ul>
|
||
<li class="right" style="margin-right: 10px">
|
||
<a href="../genindex.html" title="General Index"
|
||
>index</a></li>
|
||
<li class="right" >
|
||
<a href="../py-modindex.html" title="Python Module Index"
|
||
>modules</a> |</li>
|
||
<li class="right" >
|
||
<a href="library.html" title="Library and Extension FAQ"
|
||
>next</a> |</li>
|
||
<li class="right" >
|
||
<a href="programming.html" title="Programming FAQ"
|
||
>previous</a> |</li>
|
||
|
||
<li><img src="../_static/py.svg" alt="Python logo" style="vertical-align: middle; margin-top: -1px"/></li>
|
||
<li><a href="https://www.python.org/">Python</a> »</li>
|
||
<li class="switchers">
|
||
<div class="language_switcher_placeholder"></div>
|
||
<div class="version_switcher_placeholder"></div>
|
||
</li>
|
||
<li>
|
||
|
||
</li>
|
||
<li id="cpython-language-and-version">
|
||
<a href="../index.html">3.13.3 Documentation</a> »
|
||
</li>
|
||
|
||
<li class="nav-item nav-item-1"><a href="index.html" >Python Frequently Asked Questions</a> »</li>
|
||
<li class="nav-item nav-item-this"><a href="">Design and History FAQ</a></li>
|
||
<li class="right">
|
||
|
||
|
||
<div class="inline-search" role="search">
|
||
<form class="inline-search" action="../search.html" method="get">
|
||
<input placeholder="Quick search" aria-label="Quick search" type="search" name="q" id="search-box" />
|
||
<input type="submit" value="Go" />
|
||
</form>
|
||
</div>
|
||
|
|
||
</li>
|
||
<li class="right">
|
||
<label class="theme-selector-label">
|
||
Theme
|
||
<select class="theme-selector" oninput="activateTheme(this.value)">
|
||
<option value="auto" selected>Auto</option>
|
||
<option value="light">Light</option>
|
||
<option value="dark">Dark</option>
|
||
</select>
|
||
</label> |</li>
|
||
|
||
</ul>
|
||
</div>
|
||
<div class="footer">
|
||
©
|
||
<a href="../copyright.html">
|
||
|
||
Copyright
|
||
|
||
</a>
|
||
2001-2025, Python Software Foundation.
|
||
<br />
|
||
This page is licensed under the Python Software Foundation License Version 2.
|
||
<br />
|
||
Examples, recipes, and other code in the documentation are additionally licensed under the Zero Clause BSD License.
|
||
<br />
|
||
|
||
See <a href="/license.html">History and License</a> for more information.<br />
|
||
|
||
|
||
<br />
|
||
|
||
The Python Software Foundation is a non-profit corporation.
|
||
<a href="https://www.python.org/psf/donations/">Please donate.</a>
|
||
<br />
|
||
<br />
|
||
Last updated on Apr 08, 2025 (14:33 UTC).
|
||
|
||
<a href="/bugs.html">Found a bug</a>?
|
||
|
||
<br />
|
||
|
||
Created using <a href="https://www.sphinx-doc.org/">Sphinx</a> 8.2.3.
|
||
</div>
|
||
|
||
</body>
|
||
</html> |