|
- <!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.12.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=80d5e7a1" />
- <link rel="stylesheet" type="text/css" href="../_static/pydoctheme.css?v=bb723527" />
- <link id="pygments_dark_css" media="(prefers-color-scheme: dark)" rel="stylesheet" type="text/css" href="../_static/pygments_dark.css?v=b20cc3f5" />
-
- <script src="../_static/documentation_options.js?v=2c828074"></script>
- <script src="../_static/doctools.js?v=888ff710"></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.12.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>
-
- </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 navigation">
- <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.12.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="nc">MyVisitor</span><span class="p">:</span>
- <span class="k">def</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="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://www.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://www.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="nc">ListWrapper</span><span class="p">:</span>
- <span class="k">def</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="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="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="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="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 navigation">
- <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 navigation">
- <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.12.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-2024, 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 09, 2024 (13:47 UTC).
-
- <a href="/bugs.html">Found a bug</a>?
-
- <br />
-
- Created using <a href="https://www.sphinx-doc.org/">Sphinx</a> 7.2.6.
- </div>
-
- </body>
- </html>
|