增加python文档
This commit is contained in:
718
web/python-docs/faq/design.html
Normal file
718
web/python-docs/faq/design.html
Normal file
@@ -0,0 +1,718 @@
|
||||
|
||||
<!DOCTYPE html>
|
||||
|
||||
<html xmlns="http://www.w3.org/1999/xhtml" lang="zh_CN">
|
||||
<head>
|
||||
<meta charset="utf-8" /><meta name="generator" content="Docutils 0.17.1: http://docutils.sourceforge.net/" />
|
||||
|
||||
<title>设计和历史常见问题 — Python 3.8.20 文档</title><meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
|
||||
<link rel="stylesheet" href="../_static/pydoctheme.css" type="text/css" />
|
||||
<link rel="stylesheet" href="../_static/pygments.css" type="text/css" />
|
||||
|
||||
<script id="documentation_options" data-url_root="../" src="../_static/documentation_options.js"></script>
|
||||
<script src="../_static/jquery.js"></script>
|
||||
<script src="../_static/underscore.js"></script>
|
||||
<script src="../_static/doctools.js"></script>
|
||||
<script src="../_static/language_data.js"></script>
|
||||
<script src="../_static/translations.js"></script>
|
||||
|
||||
<script src="../_static/sidebar.js"></script>
|
||||
|
||||
<link rel="search" type="application/opensearchdescription+xml"
|
||||
title="在 Python 3.8.20 文档 中搜索"
|
||||
href="../_static/opensearch.xml"/>
|
||||
<link rel="author" title="关于这些文档" href="../about.html" />
|
||||
<link rel="index" title="索引" href="../genindex.html" />
|
||||
<link rel="search" title="搜索" href="../search.html" />
|
||||
<link rel="copyright" title="版权所有" href="../copyright.html" />
|
||||
<link rel="next" title="代码库和插件 FAQ" href="library.html" />
|
||||
<link rel="prev" title="编程常见问题" 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="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>
|
||||
|
||||
</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" />
|
||||
<label for="menuToggler" class="toggler__label">
|
||||
<span></span>
|
||||
</label>
|
||||
<nav class="nav-content" role="navigation">
|
||||
<a href="https://www.python.org/" class="nav-logo">
|
||||
<img src="../_static/py.svg" alt="Logo"/>
|
||||
</a>
|
||||
<div class="version_switcher_placeholder"></div>
|
||||
<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"
|
||||
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" fill="#444"></path>
|
||||
</svg>
|
||||
<input type="text" name="q" aria-label="快速搜索"/>
|
||||
<input type="submit" value="转向"/>
|
||||
</form>
|
||||
</nav>
|
||||
<div class="menu-wrapper">
|
||||
<nav class="menu" role="navigation" aria-label="main navigation">
|
||||
<div class="language_switcher_placeholder"></div>
|
||||
<h3><a href="../contents.html">目录</a></h3>
|
||||
<ul>
|
||||
<li><a class="reference internal" href="#">设计和历史常见问题</a><ul>
|
||||
<li><a class="reference internal" href="#why-does-python-use-indentation-for-grouping-of-statements">为什么 Python 使用缩进来分组语句?</a></li>
|
||||
<li><a class="reference internal" href="#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">为什么浮点计算不准确?</a></li>
|
||||
<li><a class="reference internal" href="#why-are-python-strings-immutable">为什么Python字符串是不可变的?</a></li>
|
||||
<li><a class="reference internal" href="#why-must-self-be-used-explicitly-in-method-definitions-and-calls">为什么必须在方法定义和调用中显式使用“self”?</a></li>
|
||||
<li><a class="reference internal" href="#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">为什么Python对某些功能(例如list.index())使用方法来实现,而其他功能(例如len(List))使用函数实现?</a></li>
|
||||
<li><a class="reference internal" href="#why-is-join-a-string-method-instead-of-a-list-or-tuple-method">为什么 join() 是一个字符串方法而不是列表或元组方法?</a></li>
|
||||
<li><a class="reference internal" href="#how-fast-are-exceptions">异常有多快?</a></li>
|
||||
<li><a class="reference internal" href="#why-isn-t-there-a-switch-or-case-statement-in-python">为什么Python中没有switch或case语句?</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">难道不能在解释器中模拟线程,而非得依赖特定于操作系统的线程实现吗?</a></li>
|
||||
<li><a class="reference internal" href="#why-can-t-lambda-expressions-contain-statements">为什么lambda表达式不能包含语句?</a></li>
|
||||
<li><a class="reference internal" href="#can-python-be-compiled-to-machine-code-c-or-some-other-language">可以将Python编译为机器代码,C或其他语言吗?</a></li>
|
||||
<li><a class="reference internal" href="#how-does-python-manage-memory">Python如何管理内存?</a></li>
|
||||
<li><a class="reference internal" href="#why-doesn-t-cpython-use-a-more-traditional-garbage-collection-scheme">为什么CPython不使用更传统的垃圾回收方案?</a></li>
|
||||
<li><a class="reference internal" href="#why-isn-t-all-memory-freed-when-cpython-exits">CPython退出时为什么不释放所有内存?</a></li>
|
||||
<li><a class="reference internal" href="#why-are-there-separate-tuple-and-list-data-types">为什么有单独的元组和列表数据类型?</a></li>
|
||||
<li><a class="reference internal" href="#how-are-lists-implemented-in-cpython">列表是如何在CPython中实现的?</a></li>
|
||||
<li><a class="reference internal" href="#how-are-dictionaries-implemented-in-cpython">字典是如何在CPython中实现的?</a></li>
|
||||
<li><a class="reference internal" href="#why-must-dictionary-keys-be-immutable">为什么字典key必须是不可变的?</a></li>
|
||||
<li><a class="reference internal" href="#why-doesn-t-list-sort-return-the-sorted-list">为什么 list.sort() 没有返回排序列表?</a></li>
|
||||
<li><a class="reference internal" href="#how-do-you-specify-and-enforce-an-interface-spec-in-python">如何在Python中指定和实施接口规范?</a></li>
|
||||
<li><a class="reference internal" href="#why-is-there-no-goto">为什么没有goto?</a></li>
|
||||
<li><a class="reference internal" href="#why-can-t-raw-strings-r-strings-end-with-a-backslash">为什么原始字符串(r-strings)不能以反斜杠结尾?</a></li>
|
||||
<li><a class="reference internal" href="#why-doesn-t-python-have-a-with-statement-for-attribute-assignments">为什么Python没有属性赋值的“with”语句?</a></li>
|
||||
<li><a class="reference internal" href="#why-are-colons-required-for-the-if-while-def-class-statements">为什么 if/while/def/class语句需要冒号?</a></li>
|
||||
<li><a class="reference internal" href="#why-does-python-allow-commas-at-the-end-of-lists-and-tuples">为什么Python在列表和元组的末尾允许使用逗号?</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<h4>上一个主题</h4>
|
||||
<p class="topless"><a href="programming.html"
|
||||
title="上一章">编程常见问题</a></p>
|
||||
<h4>下一个主题</h4>
|
||||
<p class="topless"><a href="library.html"
|
||||
title="下一章">代码库和插件 FAQ</a></p>
|
||||
<div role="note" aria-label="source link">
|
||||
<h3>本页</h3>
|
||||
<ul class="this-page-menu">
|
||||
<li><a href="../bugs.html">报告 Bug</a></li>
|
||||
<li>
|
||||
<a href="https://github.com/python/cpython/blob/3.8/Doc/faq/design.rst"
|
||||
rel="nofollow">显示源代码
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</nav>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="outdated-warning" style="padding: .5em; text-align: center; background-color: #FFBABA; color: #6A0E0E;">
|
||||
这个文档所针对的是一个已不再受支持的 Python 旧版本。
|
||||
你应当升级版本,并阅读
|
||||
<a href="/3/faq/design.html"> Python 当前稳定版本的文档</a>.
|
||||
</div>
|
||||
|
||||
<div class="related" role="navigation" aria-label="related navigation">
|
||||
<h3>导航</h3>
|
||||
<ul>
|
||||
<li class="right" style="margin-right: 10px">
|
||||
<a href="../genindex.html" title="总目录"
|
||||
accesskey="I">索引</a></li>
|
||||
<li class="right" >
|
||||
<a href="../py-modindex.html" title="Python 模块索引"
|
||||
>模块</a> |</li>
|
||||
<li class="right" >
|
||||
<a href="library.html" title="代码库和插件 FAQ"
|
||||
accesskey="N">下一页</a> |</li>
|
||||
<li class="right" >
|
||||
<a href="programming.html" title="编程常见问题"
|
||||
accesskey="P">上一页</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.8.20 Documentation</a> »
|
||||
</li>
|
||||
|
||||
<li class="nav-item nav-item-1"><a href="index.html" accesskey="U">Python 常见问题</a> »</li>
|
||||
<li class="right">
|
||||
|
||||
|
||||
<div class="inline-search" role="search">
|
||||
<form class="inline-search" action="../search.html" method="get">
|
||||
<input placeholder="快速搜索" aria-label="快速搜索" type="text" name="q" />
|
||||
<input type="submit" value="转向" />
|
||||
<input type="hidden" name="check_keywords" value="yes" />
|
||||
<input type="hidden" name="area" value="default" />
|
||||
</form>
|
||||
</div>
|
||||
|
|
||||
</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="#id3">设计和历史常见问题</a><a class="headerlink" href="#design-and-history-faq" title="永久链接至标题">¶</a></h1>
|
||||
<div class="contents topic" id="id1">
|
||||
<p class="topic-title">目录</p>
|
||||
<ul class="simple">
|
||||
<li><p><a class="reference internal" href="#design-and-history-faq" id="id3">设计和历史常见问题</a></p>
|
||||
<ul>
|
||||
<li><p><a class="reference internal" href="#why-does-python-use-indentation-for-grouping-of-statements" id="id4">为什么 Python 使用缩进来分组语句?</a></p></li>
|
||||
<li><p><a class="reference internal" href="#why-am-i-getting-strange-results-with-simple-arithmetic-operations" id="id5">为什么简单的算术运算得到奇怪的结果?</a></p></li>
|
||||
<li><p><a class="reference internal" href="#why-are-floating-point-calculations-so-inaccurate" id="id6">为什么浮点计算不准确?</a></p></li>
|
||||
<li><p><a class="reference internal" href="#why-are-python-strings-immutable" id="id7">为什么Python字符串是不可变的?</a></p></li>
|
||||
<li><p><a class="reference internal" href="#why-must-self-be-used-explicitly-in-method-definitions-and-calls" id="id8">为什么必须在方法定义和调用中显式使用“self”?</a></p></li>
|
||||
<li><p><a class="reference internal" href="#why-can-t-i-use-an-assignment-in-an-expression" id="id9">为什么不能在表达式中赋值?</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="id10">为什么Python对某些功能(例如list.index())使用方法来实现,而其他功能(例如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="id11">为什么 join() 是一个字符串方法而不是列表或元组方法?</a></p></li>
|
||||
<li><p><a class="reference internal" href="#how-fast-are-exceptions" id="id12">异常有多快?</a></p></li>
|
||||
<li><p><a class="reference internal" href="#why-isn-t-there-a-switch-or-case-statement-in-python" id="id13">为什么Python中没有switch或case语句?</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="id14">难道不能在解释器中模拟线程,而非得依赖特定于操作系统的线程实现吗?</a></p></li>
|
||||
<li><p><a class="reference internal" href="#why-can-t-lambda-expressions-contain-statements" id="id15">为什么lambda表达式不能包含语句?</a></p></li>
|
||||
<li><p><a class="reference internal" href="#can-python-be-compiled-to-machine-code-c-or-some-other-language" id="id16">可以将Python编译为机器代码,C或其他语言吗?</a></p></li>
|
||||
<li><p><a class="reference internal" href="#how-does-python-manage-memory" id="id17">Python如何管理内存?</a></p></li>
|
||||
<li><p><a class="reference internal" href="#why-doesn-t-cpython-use-a-more-traditional-garbage-collection-scheme" id="id18">为什么CPython不使用更传统的垃圾回收方案?</a></p></li>
|
||||
<li><p><a class="reference internal" href="#why-isn-t-all-memory-freed-when-cpython-exits" id="id19">CPython退出时为什么不释放所有内存?</a></p></li>
|
||||
<li><p><a class="reference internal" href="#why-are-there-separate-tuple-and-list-data-types" id="id20">为什么有单独的元组和列表数据类型?</a></p></li>
|
||||
<li><p><a class="reference internal" href="#how-are-lists-implemented-in-cpython" id="id21">列表是如何在CPython中实现的?</a></p></li>
|
||||
<li><p><a class="reference internal" href="#how-are-dictionaries-implemented-in-cpython" id="id22">字典是如何在CPython中实现的?</a></p></li>
|
||||
<li><p><a class="reference internal" href="#why-must-dictionary-keys-be-immutable" id="id23">为什么字典key必须是不可变的?</a></p></li>
|
||||
<li><p><a class="reference internal" href="#why-doesn-t-list-sort-return-the-sorted-list" id="id24">为什么 list.sort() 没有返回排序列表?</a></p></li>
|
||||
<li><p><a class="reference internal" href="#how-do-you-specify-and-enforce-an-interface-spec-in-python" id="id25">如何在Python中指定和实施接口规范?</a></p></li>
|
||||
<li><p><a class="reference internal" href="#why-is-there-no-goto" id="id26">为什么没有goto?</a></p></li>
|
||||
<li><p><a class="reference internal" href="#why-can-t-raw-strings-r-strings-end-with-a-backslash" id="id27">为什么原始字符串(r-strings)不能以反斜杠结尾?</a></p></li>
|
||||
<li><p><a class="reference internal" href="#why-doesn-t-python-have-a-with-statement-for-attribute-assignments" id="id28">为什么Python没有属性赋值的“with”语句?</a></p></li>
|
||||
<li><p><a class="reference internal" href="#why-are-colons-required-for-the-if-while-def-class-statements" id="id29">为什么 if/while/def/class语句需要冒号?</a></p></li>
|
||||
<li><p><a class="reference internal" href="#why-does-python-allow-commas-at-the-end-of-lists-and-tuples" id="id30">为什么Python在列表和元组的末尾允许使用逗号?</a></p></li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
<section id="why-does-python-use-indentation-for-grouping-of-statements">
|
||||
<h2><a class="toc-backref" href="#id4">为什么 Python 使用缩进来分组语句?</a><a class="headerlink" href="#why-does-python-use-indentation-for-grouping-of-statements" title="永久链接至标题">¶</a></h2>
|
||||
<p>Guido van Rossum 认为使用缩进进行分组非常优雅,并且大大提高了普通 Python 程序的清晰度。 大多数人在一段时间后就会喜欢上这个特性。</p>
|
||||
<p>由于没有开始/结束括号,因此解析器感知的分组与人类读者之间不会存在分歧。 偶尔 C 程序员会遇到像这样的代码片段:</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>如果条件为真,则只执行 <code class="docutils literal notranslate"><span class="pre">x++</span></code> 语句,但缩进会使你认为情况并非如此。即使是经验丰富的C程序员有时会长时间盯着它,想知道为什么即使 <code class="docutils literal notranslate"><span class="pre">x</span> <span class="pre">></span> <span class="pre">y</span></code> , <code class="docutils literal notranslate"><span class="pre">y</span></code> 也在减少。</p>
|
||||
<p>因为没有开始/结束括号,所以Python不太容易发生编码式冲突。在C中,括号可以放到许多不同的位置。如果您习惯于阅读和编写使用一种风格的代码,那么在阅读(或被要求编写)另一种风格时,您至少会感到有些不安。</p>
|
||||
<p>许多编码风格将开始/结束括号单独放在一行上。这使得程序相当长,浪费了宝贵的屏幕空间,使得更难以对程序进行全面的了解。 理想情况下,函数应该适合一个屏幕(例如,20--30行)。 20 行 Python 可以完成比 20 行 C 更多的工作。 这不仅仅是由于没有开始/结束括号 -- 无需声明以及高层级的数据类型也是其中的原因 -- 但基于缩进的语法肯定有帮助。</p>
|
||||
</section>
|
||||
<section id="why-am-i-getting-strange-results-with-simple-arithmetic-operations">
|
||||
<h2><a class="toc-backref" href="#id5">为什么简单的算术运算得到奇怪的结果?</a><a class="headerlink" href="#why-am-i-getting-strange-results-with-simple-arithmetic-operations" title="永久链接至标题">¶</a></h2>
|
||||
<p>请看下一个问题。</p>
|
||||
</section>
|
||||
<section id="why-are-floating-point-calculations-so-inaccurate">
|
||||
<h2><a class="toc-backref" href="#id6">为什么浮点计算不准确?</a><a class="headerlink" href="#why-are-floating-point-calculations-so-inaccurate" title="永久链接至标题">¶</a></h2>
|
||||
<p>用户经常对这样的结果感到惊讶:</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>并且认为这是 Python 中的一个 bug。其实不是这样。这与 Python 关系不大,而与底层平台如何处理浮点数字关系更大。</p>
|
||||
<p>CPython 中的 <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> 类型使用C语言的 <code class="docutils literal notranslate"><span class="pre">double</span></code> 类型进行存储。 <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> 对象的值是以固定的精度(通常为 53 位)存储的二进制浮点数,由于 Python 使用 C 操作,而后者依赖于处理器中的硬件实现来执行浮点运算。 这意味着就浮点运算而言,Python 的行为类似于许多流行的语言,包括 C 和 Java。</p>
|
||||
<p>许多可以轻松地用十进制表示的数字不能用二进制浮点表示。例如,在输入以下语句后:</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>为 <code class="docutils literal notranslate"><span class="pre">x</span></code> 存储的值是与十进制的值 <code class="docutils literal notranslate"><span class="pre">1.2</span></code> (非常接近) 的近似值,但不完全等于它。 在典型的机器上,实际存储的值是:</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>它对应于十进制数值:</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>典型的 53 位精度为 Python 浮点数提供了 15-16 位小数的精度。</p>
|
||||
<p>要获得更完整的解释,请参阅 Python 教程中的 <a class="reference internal" href="../tutorial/floatingpoint.html#tut-fp-issues"><span class="std std-ref">浮点算术</span></a> 一章。</p>
|
||||
</section>
|
||||
<section id="why-are-python-strings-immutable">
|
||||
<h2><a class="toc-backref" href="#id7">为什么Python字符串是不可变的?</a><a class="headerlink" href="#why-are-python-strings-immutable" title="永久链接至标题">¶</a></h2>
|
||||
<p>有几个优点。</p>
|
||||
<p>一个是性能:知道字符串是不可变的,意味着我们可以在创建时为它分配空间,并且存储需求是固定不变的。这也是元组和列表之间区别的原因之一。</p>
|
||||
<p>另一个优点是,Python 中的字符串被视为与数字一样“基本”。 任何动作都不会将值 8 更改为其他值,在 Python 中,任何动作都不会将字符串 "8" 更改为其他值。</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="#id8">为什么必须在方法定义和调用中显式使用“self”?</a><a class="headerlink" href="#why-must-self-be-used-explicitly-in-method-definitions-and-calls" title="永久链接至标题">¶</a></h2>
|
||||
<p>这个想法借鉴了 Modula-3 语言。 出于多种原因它被证明是非常有用的。</p>
|
||||
<p>首先,更明显的显示出,使用的是方法或实例属性而不是局部变量。 阅读 <code class="docutils literal notranslate"><span class="pre">self.x</span></code> 或 <code class="docutils literal notranslate"><span class="pre">self.meth()</span></code> 可以清楚地表明,即使您不知道类的定义,也会使用实例变量或方法。在 C++ 中,可以通过缺少局部变量声明来判断(假设全局变量很少见或容易识别) —— 但是在 Python 中没有局部变量声明,所以必须查找类定义才能确定。 一些 C++ 和 Java 编码标准要求实例属性具有 <code class="docutils literal notranslate"><span class="pre">m_</span></code> 前缀,因此这种显式性在这些语言中仍然有用。</p>
|
||||
<p>其次,这意味着如果要显式引用或从特定类调用该方法,不需要特殊语法。 在 C++ 中,如果你想使用在派生类中重写基类中的方法,你必须使用 <code class="docutils literal notranslate"><span class="pre">::</span></code> 运算符 -- 在 Python 中你可以编写 <code class="docutils literal notranslate"><span class="pre">baseclass.methodname(self,</span> <span class="pre"><argument</span> <span class="pre">list>)</span></code>。 这对于 <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> 方法非常有用,特别是在派生类方法想要扩展同名的基类方法,而必须以某种方式调用基类方法时。</p>
|
||||
<p>最后,它解决了变量赋值的语法问题:为了 Python 中的局部变量(根据定义!)在函数体中赋值的那些变量(并且没有明确声明为全局)赋值,就必须以某种方式告诉解释器一个赋值是为了分配一个实例变量而不是一个局部变量,它最好是通过语法实现的(出于效率原因)。 C++ 通过声明来做到这一点,但是 Python 没有声明,仅仅为了这个目的而引入它们会很可惜。 使用显式的 <code class="docutils literal notranslate"><span class="pre">self.var</span></code> 很好地解决了这个问题。 类似地,对于使用实例变量,必须编写 <code class="docutils literal notranslate"><span class="pre">self.var</span></code> 意味着对方法内部的非限定名称的引用不必搜索实例的目录。 换句话说,局部变量和实例变量存在于两个不同的命名空间中,您需要告诉 Python 使用哪个命名空间。</p>
|
||||
</section>
|
||||
<section id="why-can-t-i-use-an-assignment-in-an-expression">
|
||||
<span id="id2"></span><h2><a class="toc-backref" href="#id9">为什么不能在表达式中赋值?</a><a class="headerlink" href="#why-can-t-i-use-an-assignment-in-an-expression" title="永久链接至标题">¶</a></h2>
|
||||
<p>自 Python 3.8 开始,你能做到的!</p>
|
||||
<p>赋值表达式使用海象运算符 <cite>:=</cite> 在表达式中为变量赋值:</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>请参阅 <span class="target" id="index-4"></span><a class="pep reference external" href="https://www.python.org/dev/peps/pep-0572"><strong>PEP 572</strong></a> 了解详情。</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="#id10">为什么Python对某些功能(例如list.index())使用方法来实现,而其他功能(例如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="永久链接至标题">¶</a></h2>
|
||||
<p>正如Guido所说:</p>
|
||||
<blockquote>
|
||||
<div><p>(a) 对于某些操作,前缀表示法比后缀更容易阅读 -- 前缀(和中缀!)运算在数学中有着悠久的传统,就像在视觉上帮助数学家思考问题的记法。比较一下我们将 x*(a+b) 这样的公式改写为 x*a+x*b 的容易程度,以及使用原始OO符号做相同事情的笨拙程度。</p>
|
||||
<p>(b) 当读到写有len(X)的代码时,就知道它要求的是某件东西的长度。这告诉我们两件事:结果是一个整数,参数是某种容器。相反,当阅读x.len()时,必须已经知道x是某种实现接口的容器,或者是从具有标准len()的类继承的容器。当没有实现映射的类有get()或key()方法,或者不是文件的类有write()方法时,我们偶尔会感到困惑。</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="#id11">为什么 join() 是一个字符串方法而不是列表或元组方法?</a><a class="headerlink" href="#why-is-join-a-string-method-instead-of-a-list-or-tuple-method" title="永久链接至标题">¶</a></h2>
|
||||
<p>从 Python 1.6 开始,字符串变得更像其他标准类型,当添加方法时,这些方法提供的功能与始终使用 String 模块的函数时提供的功能相同。这些新方法中的大多数已被广泛接受,但似乎让一些程序员感到不舒服的一种方法是:</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>结果如下:</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>反对这种用法有两个常见的论点。</p>
|
||||
<p>第一条是这样的:“使用字符串文本(String Constant)的方法看起来真的很难看”,答案是也许吧,但是字符串文本只是一个固定值。如果在绑定到字符串的名称上允许使用这些方法,则没有逻辑上的理由使其在文字上不可用。</p>
|
||||
<p>第二个异议通常是这样的:“我实际上是在告诉序列使用字符串常量将其成员连接在一起”。遗憾的是并非如此。出于某种原因,把 <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> 作为一个字符串方法似乎要容易得多,因为在这种情况下,很容易看到:</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>是对字符串文本的指令,用于返回由给定分隔符分隔的子字符串(或在默认情况下,返回任意空格)。</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> 是字符串方法,因为在使用该方法时,您告诉分隔符字符串去迭代一个字符串序列,并在相邻元素之间插入自身。此方法的参数可以是任何遵循序列规则的对象,包括您自己定义的任何新的类。对于字节和字节数组对象也有类似的方法。</p>
|
||||
</section>
|
||||
<section id="how-fast-are-exceptions">
|
||||
<h2><a class="toc-backref" href="#id12">异常有多快?</a><a class="headerlink" href="#how-fast-are-exceptions" title="永久链接至标题">¶</a></h2>
|
||||
<p>如果没有引发异常,则try/except块的效率极高。实际上捕获异常是昂贵的。在2.0之前的Python版本中,通常使用这个习惯用法:</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>只有当你期望dict在任何时候都有key时,这才有意义。如果不是这样的话,你就是应该这样编码:</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>对于这种特定的情况,您还可以使用 <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>,但前提是调用 <code class="docutils literal notranslate"><span class="pre">getvalue()</span></code> 足够便宜,因为在所有情况下都会对其进行评估。</p>
|
||||
</section>
|
||||
<section id="why-isn-t-there-a-switch-or-case-statement-in-python">
|
||||
<h2><a class="toc-backref" href="#id13">为什么Python中没有switch或case语句?</a><a class="headerlink" href="#why-isn-t-there-a-switch-or-case-statement-in-python" title="永久链接至标题">¶</a></h2>
|
||||
<p>你可以通过一系列 <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>.轻松完成这项工作。对于switch语句语法已经有了一些建议,但尚未就是否以及如何进行范围测试达成共识。有关完整的详细信息和当前状态,请参阅 <span class="target" id="index-5"></span><a class="pep reference external" href="https://www.python.org/dev/peps/pep-0275"><strong>PEP 275</strong></a> 。</p>
|
||||
<p>对于需要从大量可能性中进行选择的情况,可以创建一个字典,将case 值映射到要调用的函数。例如:</p>
|
||||
<div class="highlight-python3 notranslate"><div class="highlight"><pre><span></span><span class="k">def</span> <span class="nf">function_1</span><span class="p">(</span><span class="o">...</span><span class="p">):</span>
|
||||
<span class="o">...</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="o">...</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>对于对象调用方法,可以通过使用 <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> 内置检索具有特定名称的方法来进一步简化:</p>
|
||||
<div class="highlight-python3 notranslate"><div class="highlight"><pre><span></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="p">):</span>
|
||||
<span class="o">...</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>建议对方法名使用前缀,例如本例中的 <code class="docutils literal notranslate"><span class="pre">visit_</span></code> 。如果没有这样的前缀,如果值来自不受信任的源,攻击者将能够调用对象上的任何方法。</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="#id14">难道不能在解释器中模拟线程,而非得依赖特定于操作系统的线程实现吗?</a><a class="headerlink" href="#can-t-you-emulate-threads-in-the-interpreter-instead-of-relying-on-an-os-specific-thread-implementation" title="永久链接至标题">¶</a></h2>
|
||||
<p>答案1: 不幸的是,解释器为每个Python堆栈帧推送至少一个C堆栈帧。此外,扩展可以随时回调Python。因此,一个完整的线程实现需要对C的线程支持。</p>
|
||||
<p>答案2: 幸运的是, <a class="reference external" href="https://github.com/stackless-dev/stackless/wiki">Stackless Python</a> 有一个完全重新设计的解释器循环,可以避免C堆栈。</p>
|
||||
</section>
|
||||
<section id="why-can-t-lambda-expressions-contain-statements">
|
||||
<h2><a class="toc-backref" href="#id15">为什么lambda表达式不能包含语句?</a><a class="headerlink" href="#why-can-t-lambda-expressions-contain-statements" title="永久链接至标题">¶</a></h2>
|
||||
<p>Python 的 lambda 表达式不能包含语句,因为Python的语法框架不能处理嵌套在表达式内部的语句。然而,在 Python 中,这并不是一个严重的问题。 与其他语言中添加功能的 lambda 形式不同,Python 的 lambda 只是一种速记符号,如果您懒得定义函数的话。</p>
|
||||
<p>函数已经是Python中的第一类对象,可以在本地范围内声明。 因此,使用lambda而不是本地定义的函数的唯一优点是你不需要为函数创建一个名称 -- 这只是一个分配了函数对象(与lambda表达式生成的对象类型完全相同)的局部变量!</p>
|
||||
</section>
|
||||
<section id="can-python-be-compiled-to-machine-code-c-or-some-other-language">
|
||||
<h2><a class="toc-backref" href="#id16">可以将Python编译为机器代码,C或其他语言吗?</a><a class="headerlink" href="#can-python-be-compiled-to-machine-code-c-or-some-other-language" title="永久链接至标题">¶</a></h2>
|
||||
<p><a class="reference external" href="http://cython.org/">Cython</a> 将带有可选注释的Python修改版本编译到C扩展中。 <a class="reference external" href="http://www.nuitka.net/">Nuitka</a> 是一个将Python编译成 C++ 代码的新兴编译器,旨在支持完整的Python语言。要编译成Java,可以考虑 <a class="reference external" href="https://voc.readthedocs.io">VOC</a> 。</p>
|
||||
</section>
|
||||
<section id="how-does-python-manage-memory">
|
||||
<h2><a class="toc-backref" href="#id17">Python如何管理内存?</a><a class="headerlink" href="#how-does-python-manage-memory" title="永久链接至标题">¶</a></h2>
|
||||
<p>Python 内存管理的细节取决于实现。 Python 的标准实现 <a class="reference internal" href="../glossary.html#term-cpython"><span class="xref std std-term">CPython</span></a> 使用引用计数来检测不可访问的对象,并使用另一种机制来收集引用循环,定期执行循环检测算法来查找不可访问的循环并删除所涉及的对象。 <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> 模块提供了执行垃圾回收、获取调试统计信息和优化收集器参数的函数。</p>
|
||||
<p>但是,其他实现(如 <a class="reference external" href="http://www.jython.org">Jython</a> 或 <a class="reference external" href="http://www.pypy.org">PyPy</a> ),)可以依赖不同的机制,如完全的垃圾回收器 。如果你的Python代码依赖于引用计数实现的行为,则这种差异可能会导致一些微妙的移植问题。</p>
|
||||
<p>在一些Python实现中,以下代码(在CPython中工作的很好)可能会耗尽文件描述符:</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>实际上,使用CPython的引用计数和析构函数方案, 每个新赋值的 <em>f</em> 都会关闭前一个文件。然而,对于传统的GC,这些文件对象只能以不同的时间间隔(可能很长的时间间隔)被收集(和关闭)。</p>
|
||||
<p>如果要编写可用于任何python实现的代码,则应显式关闭该文件或使用 <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> 语句;无论内存管理方案如何,这都有效:</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="#id18">为什么CPython不使用更传统的垃圾回收方案?</a><a class="headerlink" href="#why-doesn-t-cpython-use-a-more-traditional-garbage-collection-scheme" title="永久链接至标题">¶</a></h2>
|
||||
<p>首先,这不是C标准特性,因此不能移植。(是的,我们知道Boehm GC库。它包含了 <em>大多数</em> 常见平台(但不是所有平台)的汇编代码,尽管它基本上是透明的,但也不是完全透明的; 要让Python使用它,需要使用补丁。)</p>
|
||||
<p>当Python嵌入到其他应用程序中时,传统的GC也成为一个问题。在独立的Python中,可以用GC库提供的版本替换标准的malloc()和free(),嵌入Python的应用程序可能希望用 <em>它自己</em> 替代malloc()和free(),而可能不需要Python的。现在,CPython可以正确地实现malloc()和free()。</p>
|
||||
</section>
|
||||
<section id="why-isn-t-all-memory-freed-when-cpython-exits">
|
||||
<h2><a class="toc-backref" href="#id19">CPython退出时为什么不释放所有内存?</a><a class="headerlink" href="#why-isn-t-all-memory-freed-when-cpython-exits" title="永久链接至标题">¶</a></h2>
|
||||
<p>当Python退出时,从全局命名空间或Python模块引用的对象并不总是被释放。 如果存在循环引用,则可能发生这种情况 C库分配的某些内存也是不可能释放的(例如像Purify这样的工具会抱怨这些内容)。 但是,Python在退出时清理内存并尝试销毁每个对象。</p>
|
||||
<p>如果要强制 Python 在释放时删除某些内容,请使用 <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> 模块运行一个函数,强制删除这些内容。</p>
|
||||
</section>
|
||||
<section id="why-are-there-separate-tuple-and-list-data-types">
|
||||
<h2><a class="toc-backref" href="#id20">为什么有单独的元组和列表数据类型?</a><a class="headerlink" href="#why-are-there-separate-tuple-and-list-data-types" title="永久链接至标题">¶</a></h2>
|
||||
<p>虽然列表和元组在许多方面是相似的,但它们的使用方式通常是完全不同的。可以认为元组类似于Pascal记录或C结构;它们是相关数据的小集合,可以是不同类型的数据,可以作为一个组进行操作。例如,笛卡尔坐标适当地表示为两个或三个数字的元组。</p>
|
||||
<p>另一方面,列表更像其他语言中的数组。它们倾向于持有不同数量的对象,所有对象都具有相同的类型,并且逐个操作。例如, <code class="docutils literal notranslate"><span class="pre">os.listdir('.')</span></code> 返回表示当前目录中的文件的字符串列表。如果向目录中添加了一两个文件,对此输出进行操作的函数通常不会中断。</p>
|
||||
<p>元组是不可变的,这意味着一旦创建了元组,就不能用新值替换它的任何元素。列表是可变的,这意味着您始终可以更改列表的元素。只有不变元素可以用作字典的key,因此只能将元组和非列表用作key。</p>
|
||||
</section>
|
||||
<section id="how-are-lists-implemented-in-cpython">
|
||||
<h2><a class="toc-backref" href="#id21">列表是如何在CPython中实现的?</a><a class="headerlink" href="#how-are-lists-implemented-in-cpython" title="永久链接至标题">¶</a></h2>
|
||||
<p>CPython的列表实际上是可变长度的数组,而不是lisp风格的链表。该实现使用对其他对象的引用的连续数组,并在列表头结构中保留指向该数组和数组长度的指针。</p>
|
||||
<p>这使得索引列表 <code class="docutils literal notranslate"><span class="pre">a[i]</span></code> 的操作成本与列表的大小或索引的值无关。</p>
|
||||
<p>当添加或插入项时,将调整引用数组的大小。并采用了一些巧妙的方法来提高重复添加项的性能; 当数组必须增长时,会分配一些额外的空间,以便在接下来的几次中不需要实际调整大小。</p>
|
||||
</section>
|
||||
<section id="how-are-dictionaries-implemented-in-cpython">
|
||||
<h2><a class="toc-backref" href="#id22">字典是如何在CPython中实现的?</a><a class="headerlink" href="#how-are-dictionaries-implemented-in-cpython" title="永久链接至标题">¶</a></h2>
|
||||
<p>CPython的字典实现为可调整大小的哈希表。与B-树相比,这在大多数情况下为查找(目前最常见的操作)提供了更好的性能,并且实现更简单。</p>
|
||||
<p>字典的工作方式是使用 <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> 内置函数计算字典中存储的每个键的hash代码。hash代码根据键和每个进程的种子而变化很大;例如,"Python" 的hash值为-539294296,而"python"(一个按位不同的字符串)的hash值为1142331976。然后,hash代码用于计算内部数组中将存储该值的位置。假设您存储的键都具有不同的hash值,这意味着字典需要恒定的时间 -- O(1),用Big-O表示法 -- 来检索一个键。</p>
|
||||
</section>
|
||||
<section id="why-must-dictionary-keys-be-immutable">
|
||||
<h2><a class="toc-backref" href="#id23">为什么字典key必须是不可变的?</a><a class="headerlink" href="#why-must-dictionary-keys-be-immutable" title="永久链接至标题">¶</a></h2>
|
||||
<p>字典的哈希表实现使用从键值计算的哈希值来查找键。如果键是可变对象,则其值可能会发生变化,因此其哈希值也会发生变化。但是,由于无论谁更改键对象都无法判断它是否被用作字典键值,因此无法在字典中修改条目。然后,当你尝试在字典中查找相同的对象时,将无法找到它,因为其哈希值不同。如果你尝试查找旧值,也不会找到它,因为在该哈希表中找到的对象的值会有所不同。</p>
|
||||
<p>如果你想要一个用列表索引的字典,只需先将列表转换为元组;用函数 <code class="docutils literal notranslate"><span class="pre">tuple(L)</span></code> 创建一个元组,其条目与列表 <code class="docutils literal notranslate"><span class="pre">L</span></code> 相同。 元组是不可变的,因此可以用作字典键。</p>
|
||||
<p>已经提出的一些不可接受的解决方案:</p>
|
||||
<ul>
|
||||
<li><p>哈希按其地址(对象ID)列出。这不起作用,因为如果你构造一个具有相同值的新列表,它将无法找到;例如:</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>会引发一个 <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> 异常,因为第二行中使用的 <code class="docutils literal notranslate"><span class="pre">[1,</span> <span class="pre">2]</span></code> 的 id 与第一行中的 id 不同。换句话说,应该使用 <code class="docutils literal notranslate"><span class="pre">==</span></code> 来比较字典键,而不是使用 <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>使用列表作为键时进行复制。这没有用的,因为作为可变对象的列表可以包含对自身的引用,然后复制代码将进入无限循环。</p></li>
|
||||
<li><p>允许列表作为键,但告诉用户不要修改它们。当你意外忘记或修改列表时,这将产生程序中的一类难以跟踪的错误。它还使一个重要的字典不变量无效: <code class="docutils literal notranslate"><span class="pre">d.keys()</span></code> 中的每个值都可用作字典的键。</p></li>
|
||||
<li><p>将列表用作字典键后,应标记为其只读。问题是,它不仅仅是可以改变其值的顶级对象;你可以使用包含列表作为键的元组。将任何内容作为键关联到字典中都需要将从那里可到达的所有对象标记为只读 —— 并且自引用对象可能会导致无限循环。</p></li>
|
||||
</ul>
|
||||
<p>如果需要,可以使用以下方法来解决这个问题,但使用它需要你自担风险:你可以将一个可变结构包装在一个类实例中,该实例同时具有 <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> 和 <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> 方法。然后,你必须确保驻留在字典(或其他基于 hash 的结构)中的所有此类包装器对象的哈希值在对象位于字典(或其他结构)中时保持固定。:</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>注意,哈希计算由于列表的某些成员可能不可用以及算术溢出的可能性而变得复杂。</p>
|
||||
<p>此外,必须始终如此,如果 <code class="docutils literal notranslate"><span class="pre">o1</span> <span class="pre">==</span> <span class="pre">o2</span></code> (即 <code class="docutils literal notranslate"><span class="pre">o1.__eq__(o2)</span> <span class="pre">is</span> <span class="pre">True</span></code> )则 <code class="docutils literal notranslate"><span class="pre">hash(o1)</span> <span class="pre">==</span> <span class="pre">hash(o2)</span></code> (即 <code class="docutils literal notranslate"><span class="pre">o1.__hash__()</span> <span class="pre">==</span> <span class="pre">o2.__hash__()</span></code> ),无论对象是否在字典中。 如果你不能满足这些限制,字典和其他基于 hash 的结构将会出错。</p>
|
||||
<p>对于 ListWrapper ,只要包装器对象在字典中,包装列表就不能更改以避免异常。除非你准备好认真考虑需求以及不正确地满足这些需求的后果,否则不要这样做。请留意。</p>
|
||||
</section>
|
||||
<section id="why-doesn-t-list-sort-return-the-sorted-list">
|
||||
<h2><a class="toc-backref" href="#id24">为什么 list.sort() 没有返回排序列表?</a><a class="headerlink" href="#why-doesn-t-list-sort-return-the-sorted-list" title="永久链接至标题">¶</a></h2>
|
||||
<p>在性能很重要的情况下,仅仅为了排序而复制一份列表将是一种浪费。因此, <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> 对列表进行了适当的排序。为了提醒您这一事实,它不会返回已排序的列表。这样,当您需要排序的副本,但也需要保留未排序的版本时,就不会意外地覆盖列表。</p>
|
||||
<p>如果要返回新列表,请使用内置 <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> 函数。此函数从提供的可迭代列表中创建新列表,对其进行排序并返回。例如,下面是如何迭代遍历字典并按keys排序:</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="#id25">如何在Python中指定和实施接口规范?</a><a class="headerlink" href="#how-do-you-specify-and-enforce-an-interface-spec-in-python" title="永久链接至标题">¶</a></h2>
|
||||
<p>由C++和Java等语言提供的模块接口规范描述了模块的方法和函数的原型。许多人认为接口规范的编译时强制执行有助于构建大型程序。</p>
|
||||
<p>Python 2.6添加了一个 <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> 模块,允许定义抽象基类 (ABCs)。然后可以使用 <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> 和 <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> 来检查实例或类是否实现了特定的ABC。 <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> 模块定义了一组有用的ABCs 例如 <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> , 和 <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>对于 Python,接口规范的许多好处可以通过组件的适当测试规程来获得。</p>
|
||||
<p>一个好的模块测试套件既可以提供回归测试,也可以作为模块接口规范和一组示例。许多Python模块可以作为脚本运行,以提供简单的“自我测试”。即使是使用复杂外部接口的模块,也常常可以使用外部接口的简单“桩代码(stub)”模拟进行隔离测试。可以使用 <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> 和 <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> 模块或第三方测试框架来构造详尽的测试套件,以运行模块中的每一行代码。</p>
|
||||
<p>适当的测试规程可以帮助在Python中构建大型的、复杂的应用程序以及接口规范。事实上,它可能会更好,因为接口规范不能测试程序的某些属性。例如, <code class="xref py py-meth docutils literal notranslate"><span class="pre">append()</span></code> 方法将向一些内部列表的末尾添加新元素;接口规范不能测试您的 <code class="xref py py-meth docutils literal notranslate"><span class="pre">append()</span></code> 实现是否能够正确执行此操作,但是在测试套件中检查这个属性是很简单的。</p>
|
||||
<p>编写测试套件非常有用,您可能希望设计代码时着眼于使其易于测试。一种日益流行的技术是面向测试的开发,它要求在编写任何实际代码之前,首先编写测试套件的各个部分。当然,Python允许您草率行事,根本不编写测试用例。</p>
|
||||
</section>
|
||||
<section id="why-is-there-no-goto">
|
||||
<h2><a class="toc-backref" href="#id26">为什么没有goto?</a><a class="headerlink" href="#why-is-there-no-goto" title="永久链接至标题">¶</a></h2>
|
||||
<p>在 1970 年代人们了解到不受限制的 goto 可能导致混乱得像“意大利面”那样难以理解和修改的代码。 在高级语言中,它也是不必要的,只需有实现分支 (在 Python 中是使用 <code class="docutils literal notranslate"><span class="pre">if</span></code> 语句以及 <code class="docutils literal notranslate"><span class="pre">or</span></code>, <code class="docutils literal notranslate"><span class="pre">and</span></code> 和 <code class="docutils literal notranslate"><span class="pre">if-else</span></code> 表达式) 和循环 (使用 <code class="docutils literal notranslate"><span class="pre">while</span></code> 和 <code class="docutils literal notranslate"><span class="pre">for</span></code> 语句,并可能包含 <code class="docutils literal notranslate"><span class="pre">continue</span></code> 和 <code class="docutils literal notranslate"><span class="pre">break</span></code>) 的手段就足够了。</p>
|
||||
<p>人们还可以使用异常捕获来提供甚至能跨函数调用的“结构化 goto”。 许多人认为异常可以方便地模拟 C, Fortran 和其他语言中所有合理使用的“go”或“goto”构造。 例如:</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>但是不允许你跳到循环的中间,这通常被认为是滥用goto。谨慎使用。</p>
|
||||
</section>
|
||||
<section id="why-can-t-raw-strings-r-strings-end-with-a-backslash">
|
||||
<h2><a class="toc-backref" href="#id27">为什么原始字符串(r-strings)不能以反斜杠结尾?</a><a class="headerlink" href="#why-can-t-raw-strings-r-strings-end-with-a-backslash" title="永久链接至标题">¶</a></h2>
|
||||
<p>更准确地说,它们不能以奇数个反斜杠结束:结尾处的不成对反斜杠会转义结束引号字符,留下未结束的字符串。</p>
|
||||
<p>原始字符串的设计是为了方便想要执行自己的反斜杠转义处理的处理器(主要是正则表达式引擎)创建输入。此类处理器将不匹配的尾随反斜杠视为错误,因此原始字符串不允许这样做。反过来,允许通过使用引号字符转义反斜杠转义字符串。当r-string用于它们的预期目的时,这些规则工作的很好。</p>
|
||||
<p>如果您正在尝试构建Windows路径名,请注意所有Windows系统调用都使用正斜杠:</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>如果您正在尝试为DOS命令构建路径名,请尝试以下示例</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="#id28">为什么Python没有属性赋值的“with”语句?</a><a class="headerlink" href="#why-doesn-t-python-have-a-with-statement-for-attribute-assignments" title="永久链接至标题">¶</a></h2>
|
||||
<p>Python有一个 'with' 语句,它封装了块的执行,在块的入口和出口调用代码。有些语言的结构是这样的:</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>在Python中,这样的结构是不明确的。</p>
|
||||
<p>其他语言,如ObjectPascal、Delphi和C++ 使用静态类型,因此可以毫不含糊地知道分配给什么成员。这是静态类型的要点 -- 编译器 <em>总是</em> 在编译时知道每个变量的作用域。</p>
|
||||
<p>Python使用动态类型。事先不可能知道在运行时引用哪个属性。可以动态地在对象中添加或删除成员属性。这使得无法通过简单的阅读就知道引用的是什么属性:局部属性、全局属性还是成员属性?</p>
|
||||
<p>例如,采用以下不完整的代码段:</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>该代码段假设 "a" 必须有一个名为 "x" 的成员属性。然而,Python中并没有告诉解释器这一点。假设 "a" 是整数,会发生什么?如果有一个名为 "x" 的全局变量,它是否会在with块中使用?如您所见,Python的动态特性使得这样的选择更加困难。</p>
|
||||
<p>然而,Python 可以通过赋值轻松实现 "with" 和类似语言特性(减少代码量)的主要好处。代替:</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>写成这样:</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>这也具有提高执行速度的附带效果,因为 Python 在运行时解析名称绑定,而第二个版本只需要执行一次解析。</p>
|
||||
</section>
|
||||
<section id="why-are-colons-required-for-the-if-while-def-class-statements">
|
||||
<h2><a class="toc-backref" href="#id29">为什么 if/while/def/class语句需要冒号?</a><a class="headerlink" href="#why-are-colons-required-for-the-if-while-def-class-statements" title="永久链接至标题">¶</a></h2>
|
||||
<p>冒号主要用于增强可读性(ABC语言实验的结果之一)。考虑一下这个:</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>与</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>注意第二种方法稍微容易一些。请进一步注意,在这个FAQ解答的示例中,冒号是如何设置的;这是英语中的标准用法。</p>
|
||||
<p>另一个次要原因是冒号使带有语法突出显示的编辑器更容易工作;他们可以寻找冒号来决定何时需要增加缩进,而不必对程序文本进行更精细的解析。</p>
|
||||
</section>
|
||||
<section id="why-does-python-allow-commas-at-the-end-of-lists-and-tuples">
|
||||
<h2><a class="toc-backref" href="#id30">为什么Python在列表和元组的末尾允许使用逗号?</a><a class="headerlink" href="#why-does-python-allow-commas-at-the-end-of-lists-and-tuples" title="永久链接至标题">¶</a></h2>
|
||||
<p>Python 允许您在列表,元组和字典的末尾添加一个尾随逗号:</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>有几个理由允许这样做。</p>
|
||||
<p>如果列表,元组或字典的字面值分布在多行中,则更容易添加更多元素,因为不必记住在上一行中添加逗号。这些行也可以重新排序,而不会产生语法错误。</p>
|
||||
<p>不小心省略逗号会导致难以诊断的错误。例如:</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>这个列表看起来有四个元素,但实际上包含三个 : "fee", "fiefoo" 和 "fum" 。总是加上逗号可以避免这个错误的来源。</p>
|
||||
<p>允许尾随逗号也可以使编程代码更容易生成。</p>
|
||||
</section>
|
||||
</section>
|
||||
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="sphinxsidebar" role="navigation" aria-label="main navigation">
|
||||
<div class="sphinxsidebarwrapper">
|
||||
<h3><a href="../contents.html">目录</a></h3>
|
||||
<ul>
|
||||
<li><a class="reference internal" href="#">设计和历史常见问题</a><ul>
|
||||
<li><a class="reference internal" href="#why-does-python-use-indentation-for-grouping-of-statements">为什么 Python 使用缩进来分组语句?</a></li>
|
||||
<li><a class="reference internal" href="#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">为什么浮点计算不准确?</a></li>
|
||||
<li><a class="reference internal" href="#why-are-python-strings-immutable">为什么Python字符串是不可变的?</a></li>
|
||||
<li><a class="reference internal" href="#why-must-self-be-used-explicitly-in-method-definitions-and-calls">为什么必须在方法定义和调用中显式使用“self”?</a></li>
|
||||
<li><a class="reference internal" href="#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">为什么Python对某些功能(例如list.index())使用方法来实现,而其他功能(例如len(List))使用函数实现?</a></li>
|
||||
<li><a class="reference internal" href="#why-is-join-a-string-method-instead-of-a-list-or-tuple-method">为什么 join() 是一个字符串方法而不是列表或元组方法?</a></li>
|
||||
<li><a class="reference internal" href="#how-fast-are-exceptions">异常有多快?</a></li>
|
||||
<li><a class="reference internal" href="#why-isn-t-there-a-switch-or-case-statement-in-python">为什么Python中没有switch或case语句?</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">难道不能在解释器中模拟线程,而非得依赖特定于操作系统的线程实现吗?</a></li>
|
||||
<li><a class="reference internal" href="#why-can-t-lambda-expressions-contain-statements">为什么lambda表达式不能包含语句?</a></li>
|
||||
<li><a class="reference internal" href="#can-python-be-compiled-to-machine-code-c-or-some-other-language">可以将Python编译为机器代码,C或其他语言吗?</a></li>
|
||||
<li><a class="reference internal" href="#how-does-python-manage-memory">Python如何管理内存?</a></li>
|
||||
<li><a class="reference internal" href="#why-doesn-t-cpython-use-a-more-traditional-garbage-collection-scheme">为什么CPython不使用更传统的垃圾回收方案?</a></li>
|
||||
<li><a class="reference internal" href="#why-isn-t-all-memory-freed-when-cpython-exits">CPython退出时为什么不释放所有内存?</a></li>
|
||||
<li><a class="reference internal" href="#why-are-there-separate-tuple-and-list-data-types">为什么有单独的元组和列表数据类型?</a></li>
|
||||
<li><a class="reference internal" href="#how-are-lists-implemented-in-cpython">列表是如何在CPython中实现的?</a></li>
|
||||
<li><a class="reference internal" href="#how-are-dictionaries-implemented-in-cpython">字典是如何在CPython中实现的?</a></li>
|
||||
<li><a class="reference internal" href="#why-must-dictionary-keys-be-immutable">为什么字典key必须是不可变的?</a></li>
|
||||
<li><a class="reference internal" href="#why-doesn-t-list-sort-return-the-sorted-list">为什么 list.sort() 没有返回排序列表?</a></li>
|
||||
<li><a class="reference internal" href="#how-do-you-specify-and-enforce-an-interface-spec-in-python">如何在Python中指定和实施接口规范?</a></li>
|
||||
<li><a class="reference internal" href="#why-is-there-no-goto">为什么没有goto?</a></li>
|
||||
<li><a class="reference internal" href="#why-can-t-raw-strings-r-strings-end-with-a-backslash">为什么原始字符串(r-strings)不能以反斜杠结尾?</a></li>
|
||||
<li><a class="reference internal" href="#why-doesn-t-python-have-a-with-statement-for-attribute-assignments">为什么Python没有属性赋值的“with”语句?</a></li>
|
||||
<li><a class="reference internal" href="#why-are-colons-required-for-the-if-while-def-class-statements">为什么 if/while/def/class语句需要冒号?</a></li>
|
||||
<li><a class="reference internal" href="#why-does-python-allow-commas-at-the-end-of-lists-and-tuples">为什么Python在列表和元组的末尾允许使用逗号?</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<h4>上一个主题</h4>
|
||||
<p class="topless"><a href="programming.html"
|
||||
title="上一章">编程常见问题</a></p>
|
||||
<h4>下一个主题</h4>
|
||||
<p class="topless"><a href="library.html"
|
||||
title="下一章">代码库和插件 FAQ</a></p>
|
||||
<div role="note" aria-label="source link">
|
||||
<h3>本页</h3>
|
||||
<ul class="this-page-menu">
|
||||
<li><a href="../bugs.html">报告 Bug</a></li>
|
||||
<li>
|
||||
<a href="https://github.com/python/cpython/blob/3.8/Doc/faq/design.rst"
|
||||
rel="nofollow">显示源代码
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="clearer"></div>
|
||||
</div>
|
||||
<div class="related" role="navigation" aria-label="related navigation">
|
||||
<h3>导航</h3>
|
||||
<ul>
|
||||
<li class="right" style="margin-right: 10px">
|
||||
<a href="../genindex.html" title="总目录"
|
||||
>索引</a></li>
|
||||
<li class="right" >
|
||||
<a href="../py-modindex.html" title="Python 模块索引"
|
||||
>模块</a> |</li>
|
||||
<li class="right" >
|
||||
<a href="library.html" title="代码库和插件 FAQ"
|
||||
>下一页</a> |</li>
|
||||
<li class="right" >
|
||||
<a href="programming.html" title="编程常见问题"
|
||||
>上一页</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.8.20 Documentation</a> »
|
||||
</li>
|
||||
|
||||
<li class="nav-item nav-item-1"><a href="index.html" >Python 常见问题</a> »</li>
|
||||
<li class="right">
|
||||
|
||||
|
||||
<div class="inline-search" role="search">
|
||||
<form class="inline-search" action="../search.html" method="get">
|
||||
<input placeholder="快速搜索" aria-label="快速搜索" type="text" name="q" />
|
||||
<input type="submit" value="转向" />
|
||||
<input type="hidden" name="check_keywords" value="yes" />
|
||||
<input type="hidden" name="area" value="default" />
|
||||
</form>
|
||||
</div>
|
||||
|
|
||||
</li>
|
||||
|
||||
</ul>
|
||||
</div>
|
||||
<div class="footer">
|
||||
© <a href="../copyright.html">版权所有</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 />
|
||||
|
||||
<br />
|
||||
|
||||
The Python Software Foundation is a non-profit corporation.
|
||||
<a href="https://www.python.org/psf/donations/">Please donate.</a>
|
||||
<br />
|
||||
<br />
|
||||
|
||||
最后更新于 12月 09, 2024.
|
||||
<a href="https://docs.python.org/3/bugs.html">Found a bug</a>?
|
||||
<br />
|
||||
|
||||
Created using <a href="https://www.sphinx-doc.org/">Sphinx</a> 2.4.4.
|
||||
</div>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
614
web/python-docs/faq/extending.html
Normal file
614
web/python-docs/faq/extending.html
Normal file
@@ -0,0 +1,614 @@
|
||||
|
||||
<!DOCTYPE html>
|
||||
|
||||
<html xmlns="http://www.w3.org/1999/xhtml" lang="zh_CN">
|
||||
<head>
|
||||
<meta charset="utf-8" /><meta name="generator" content="Docutils 0.17.1: http://docutils.sourceforge.net/" />
|
||||
|
||||
<title>扩展/嵌入常见问题 — Python 3.8.20 文档</title><meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
|
||||
<link rel="stylesheet" href="../_static/pydoctheme.css" type="text/css" />
|
||||
<link rel="stylesheet" href="../_static/pygments.css" type="text/css" />
|
||||
|
||||
<script id="documentation_options" data-url_root="../" src="../_static/documentation_options.js"></script>
|
||||
<script src="../_static/jquery.js"></script>
|
||||
<script src="../_static/underscore.js"></script>
|
||||
<script src="../_static/doctools.js"></script>
|
||||
<script src="../_static/language_data.js"></script>
|
||||
<script src="../_static/translations.js"></script>
|
||||
|
||||
<script src="../_static/sidebar.js"></script>
|
||||
|
||||
<link rel="search" type="application/opensearchdescription+xml"
|
||||
title="在 Python 3.8.20 文档 中搜索"
|
||||
href="../_static/opensearch.xml"/>
|
||||
<link rel="author" title="关于这些文档" href="../about.html" />
|
||||
<link rel="index" title="索引" href="../genindex.html" />
|
||||
<link rel="search" title="搜索" href="../search.html" />
|
||||
<link rel="copyright" title="版权所有" href="../copyright.html" />
|
||||
<link rel="next" title="Python在Windows上的常见问题" href="windows.html" />
|
||||
<link rel="prev" title="代码库和插件 FAQ" href="library.html" />
|
||||
<link rel="canonical" href="https://docs.python.org/3/faq/extending.html" />
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<style>
|
||||
@media only screen {
|
||||
table.full-width-table {
|
||||
width: 100%;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
<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>
|
||||
|
||||
</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" />
|
||||
<label for="menuToggler" class="toggler__label">
|
||||
<span></span>
|
||||
</label>
|
||||
<nav class="nav-content" role="navigation">
|
||||
<a href="https://www.python.org/" class="nav-logo">
|
||||
<img src="../_static/py.svg" alt="Logo"/>
|
||||
</a>
|
||||
<div class="version_switcher_placeholder"></div>
|
||||
<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"
|
||||
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" fill="#444"></path>
|
||||
</svg>
|
||||
<input type="text" name="q" aria-label="快速搜索"/>
|
||||
<input type="submit" value="转向"/>
|
||||
</form>
|
||||
</nav>
|
||||
<div class="menu-wrapper">
|
||||
<nav class="menu" role="navigation" aria-label="main navigation">
|
||||
<div class="language_switcher_placeholder"></div>
|
||||
<h3><a href="../contents.html">目录</a></h3>
|
||||
<ul>
|
||||
<li><a class="reference internal" href="#">扩展/嵌入常见问题</a><ul>
|
||||
<li><a class="reference internal" href="#can-i-create-my-own-functions-in-c">可以使用 C 语言创建自己的函数吗?</a></li>
|
||||
<li><a class="reference internal" href="#id2">可以使用 C++ 语言创建自己的函数吗?</a></li>
|
||||
<li><a class="reference internal" href="#writing-c-is-hard-are-there-any-alternatives">C很难写,有没有其他选择?</a></li>
|
||||
<li><a class="reference internal" href="#how-can-i-execute-arbitrary-python-statements-from-c">如何在 C 中执行任意 Python 语句?</a></li>
|
||||
<li><a class="reference internal" href="#how-can-i-evaluate-an-arbitrary-python-expression-from-c">如何在 C 中对任意 Python 表达式求值?</a></li>
|
||||
<li><a class="reference internal" href="#how-do-i-extract-c-values-from-a-python-object">如何从Python对象中提取C的值?</a></li>
|
||||
<li><a class="reference internal" href="#how-do-i-use-py-buildvalue-to-create-a-tuple-of-arbitrary-length">如何使用Py_BuildValue()创建任意长度的元组?</a></li>
|
||||
<li><a class="reference internal" href="#how-do-i-call-an-object-s-method-from-c">如何从C调用对象的方法?</a></li>
|
||||
<li><a class="reference internal" href="#how-do-i-catch-the-output-from-pyerr-print-or-anything-that-prints-to-stdout-stderr">如何捕获PyErr_Print()(或打印到stdout / stderr的任何内容)的输出?</a></li>
|
||||
<li><a class="reference internal" href="#how-do-i-access-a-module-written-in-python-from-c">如何从C访问用Python编写的模块?</a></li>
|
||||
<li><a class="reference internal" href="#how-do-i-interface-to-c-objects-from-python">如何在 Python 中对接 C ++ 对象?</a></li>
|
||||
<li><a class="reference internal" href="#i-added-a-module-using-the-setup-file-and-the-make-fails-why">我使用Setup文件添加了一个模块,为什么make失败了?</a></li>
|
||||
<li><a class="reference internal" href="#how-do-i-debug-an-extension">如何调试扩展?</a></li>
|
||||
<li><a class="reference internal" href="#i-want-to-compile-a-python-module-on-my-linux-system-but-some-files-are-missing-why">我想在Linux系统上编译一个Python模块,但是缺少一些文件。为什么?</a></li>
|
||||
<li><a class="reference internal" href="#how-do-i-tell-incomplete-input-from-invalid-input">如何区分“输入不完整”和“输入无效”?</a></li>
|
||||
<li><a class="reference internal" href="#how-do-i-find-undefined-g-symbols-builtin-new-or-pure-virtual">如何找到未定义的g++符号__builtin_new或__pure_virtual?</a></li>
|
||||
<li><a class="reference internal" href="#can-i-create-an-object-class-with-some-methods-implemented-in-c-and-others-in-python-e-g-through-inheritance">能否创建一个对象类,其中部分方法在C中实现,而其他方法在Python中实现(例如通过继承)?</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<h4>上一个主题</h4>
|
||||
<p class="topless"><a href="library.html"
|
||||
title="上一章">代码库和插件 FAQ</a></p>
|
||||
<h4>下一个主题</h4>
|
||||
<p class="topless"><a href="windows.html"
|
||||
title="下一章">Python在Windows上的常见问题</a></p>
|
||||
<div role="note" aria-label="source link">
|
||||
<h3>本页</h3>
|
||||
<ul class="this-page-menu">
|
||||
<li><a href="../bugs.html">报告 Bug</a></li>
|
||||
<li>
|
||||
<a href="https://github.com/python/cpython/blob/3.8/Doc/faq/extending.rst"
|
||||
rel="nofollow">显示源代码
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</nav>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="outdated-warning" style="padding: .5em; text-align: center; background-color: #FFBABA; color: #6A0E0E;">
|
||||
这个文档所针对的是一个已不再受支持的 Python 旧版本。
|
||||
你应当升级版本,并阅读
|
||||
<a href="/3/faq/extending.html"> Python 当前稳定版本的文档</a>.
|
||||
</div>
|
||||
|
||||
<div class="related" role="navigation" aria-label="related navigation">
|
||||
<h3>导航</h3>
|
||||
<ul>
|
||||
<li class="right" style="margin-right: 10px">
|
||||
<a href="../genindex.html" title="总目录"
|
||||
accesskey="I">索引</a></li>
|
||||
<li class="right" >
|
||||
<a href="../py-modindex.html" title="Python 模块索引"
|
||||
>模块</a> |</li>
|
||||
<li class="right" >
|
||||
<a href="windows.html" title="Python在Windows上的常见问题"
|
||||
accesskey="N">下一页</a> |</li>
|
||||
<li class="right" >
|
||||
<a href="library.html" title="代码库和插件 FAQ"
|
||||
accesskey="P">上一页</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.8.20 Documentation</a> »
|
||||
</li>
|
||||
|
||||
<li class="nav-item nav-item-1"><a href="index.html" accesskey="U">Python 常见问题</a> »</li>
|
||||
<li class="right">
|
||||
|
||||
|
||||
<div class="inline-search" role="search">
|
||||
<form class="inline-search" action="../search.html" method="get">
|
||||
<input placeholder="快速搜索" aria-label="快速搜索" type="text" name="q" />
|
||||
<input type="submit" value="转向" />
|
||||
<input type="hidden" name="check_keywords" value="yes" />
|
||||
<input type="hidden" name="area" value="default" />
|
||||
</form>
|
||||
</div>
|
||||
|
|
||||
</li>
|
||||
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<div class="document">
|
||||
<div class="documentwrapper">
|
||||
<div class="bodywrapper">
|
||||
<div class="body" role="main">
|
||||
|
||||
<section id="extending-embedding-faq">
|
||||
<h1><a class="toc-backref" href="#id3">扩展/嵌入常见问题</a><a class="headerlink" href="#extending-embedding-faq" title="永久链接至标题">¶</a></h1>
|
||||
<div class="contents topic" id="id1">
|
||||
<p class="topic-title">目录</p>
|
||||
<ul class="simple">
|
||||
<li><p><a class="reference internal" href="#extending-embedding-faq" id="id3">扩展/嵌入常见问题</a></p>
|
||||
<ul>
|
||||
<li><p><a class="reference internal" href="#can-i-create-my-own-functions-in-c" id="id4">可以使用 C 语言创建自己的函数吗?</a></p></li>
|
||||
<li><p><a class="reference internal" href="#id2" id="id5">可以使用 C++ 语言创建自己的函数吗?</a></p></li>
|
||||
<li><p><a class="reference internal" href="#writing-c-is-hard-are-there-any-alternatives" id="id6">C很难写,有没有其他选择?</a></p></li>
|
||||
<li><p><a class="reference internal" href="#how-can-i-execute-arbitrary-python-statements-from-c" id="id7">如何在 C 中执行任意 Python 语句?</a></p></li>
|
||||
<li><p><a class="reference internal" href="#how-can-i-evaluate-an-arbitrary-python-expression-from-c" id="id8">如何在 C 中对任意 Python 表达式求值?</a></p></li>
|
||||
<li><p><a class="reference internal" href="#how-do-i-extract-c-values-from-a-python-object" id="id9">如何从Python对象中提取C的值?</a></p></li>
|
||||
<li><p><a class="reference internal" href="#how-do-i-use-py-buildvalue-to-create-a-tuple-of-arbitrary-length" id="id10">如何使用Py_BuildValue()创建任意长度的元组?</a></p></li>
|
||||
<li><p><a class="reference internal" href="#how-do-i-call-an-object-s-method-from-c" id="id11">如何从C调用对象的方法?</a></p></li>
|
||||
<li><p><a class="reference internal" href="#how-do-i-catch-the-output-from-pyerr-print-or-anything-that-prints-to-stdout-stderr" id="id12">如何捕获PyErr_Print()(或打印到stdout / stderr的任何内容)的输出?</a></p></li>
|
||||
<li><p><a class="reference internal" href="#how-do-i-access-a-module-written-in-python-from-c" id="id13">如何从C访问用Python编写的模块?</a></p></li>
|
||||
<li><p><a class="reference internal" href="#how-do-i-interface-to-c-objects-from-python" id="id14">如何在 Python 中对接 C ++ 对象?</a></p></li>
|
||||
<li><p><a class="reference internal" href="#i-added-a-module-using-the-setup-file-and-the-make-fails-why" id="id15">我使用Setup文件添加了一个模块,为什么make失败了?</a></p></li>
|
||||
<li><p><a class="reference internal" href="#how-do-i-debug-an-extension" id="id16">如何调试扩展?</a></p></li>
|
||||
<li><p><a class="reference internal" href="#i-want-to-compile-a-python-module-on-my-linux-system-but-some-files-are-missing-why" id="id17">我想在Linux系统上编译一个Python模块,但是缺少一些文件。为什么?</a></p></li>
|
||||
<li><p><a class="reference internal" href="#how-do-i-tell-incomplete-input-from-invalid-input" id="id18">如何区分“输入不完整”和“输入无效”?</a></p></li>
|
||||
<li><p><a class="reference internal" href="#how-do-i-find-undefined-g-symbols-builtin-new-or-pure-virtual" id="id19">如何找到未定义的g++符号__builtin_new或__pure_virtual?</a></p></li>
|
||||
<li><p><a class="reference internal" href="#can-i-create-an-object-class-with-some-methods-implemented-in-c-and-others-in-python-e-g-through-inheritance" id="id20">能否创建一个对象类,其中部分方法在C中实现,而其他方法在Python中实现(例如通过继承)?</a></p></li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
<section id="can-i-create-my-own-functions-in-c">
|
||||
<h2><a class="toc-backref" href="#id4">可以使用 C 语言创建自己的函数吗?</a><a class="headerlink" href="#can-i-create-my-own-functions-in-c" title="永久链接至标题">¶</a></h2>
|
||||
<p>是的,您可以在C中创建包含函数、变量、异常甚至新类型的内置模块。在文档 <a class="reference internal" href="../extending/index.html#extending-index"><span class="std std-ref">扩展和嵌入 Python 解释器</span></a> 中有说明。</p>
|
||||
<p>大多数中级或高级的Python书籍也涵盖这个主题。</p>
|
||||
</section>
|
||||
<section id="id2">
|
||||
<h2><a class="toc-backref" href="#id5">可以使用 C++ 语言创建自己的函数吗?</a><a class="headerlink" href="#id2" title="永久链接至标题">¶</a></h2>
|
||||
<p>是的,可以使用C ++中兼容C的功能。 在Python include文件周围放置` <cite>extern“C”{...}`</cite> ,并在Python解释器调用的每个函数之前放置 <code class="docutils literal notranslate"><span class="pre">extern“C”</span></code> 。 具有构造函数的全局或静态C ++对象可能不是一个好主意。</p>
|
||||
</section>
|
||||
<section id="writing-c-is-hard-are-there-any-alternatives">
|
||||
<span id="c-wrapper-software"></span><h2><a class="toc-backref" href="#id6">C很难写,有没有其他选择?</a><a class="headerlink" href="#writing-c-is-hard-are-there-any-alternatives" title="永久链接至标题">¶</a></h2>
|
||||
<p>编写自己的C扩展有很多选择,具体取决于您要做的事情。</p>
|
||||
<p><a class="reference external" href="http://cython.org">Cython</a> 及其相关的 <a class="reference external" href="https://www.cosc.canterbury.ac.nz/greg.ewing/python/Pyrex/">Pyrex</a> 是接受稍微修改过的Python形式并生成相应C代码的编译器。 Cython和Pyrex可以编写扩展而无需学习Python的C API。</p>
|
||||
<p>如果需要连接到某些当前不存在Python扩展的C或C ++库,可以尝试使用 <a class="reference external" href="http://www.swig.org">SWIG</a> 等工具包装库的数据类型和函数。 <a class="reference external" href="https://riverbankcomputing.com/software/sip/intro">SIP</a> , <a class="reference external" href="http://cxx.sourceforge.net/">CXX</a> <a class="reference external" href="http://www.boost.org/libs/python/doc/index.html">Boost</a> , 或 <a class="reference external" href="https://github.com/scipy/weave">Weave</a> 也是包装C ++库的替代方案。</p>
|
||||
</section>
|
||||
<section id="how-can-i-execute-arbitrary-python-statements-from-c">
|
||||
<h2><a class="toc-backref" href="#id7">如何在 C 中执行任意 Python 语句?</a><a class="headerlink" href="#how-can-i-execute-arbitrary-python-statements-from-c" title="永久链接至标题">¶</a></h2>
|
||||
<p>执行此操作的最高层级函数为 <a class="reference internal" href="../c-api/veryhigh.html#c.PyRun_SimpleString" title="PyRun_SimpleString"><code class="xref c c-func docutils literal notranslate"><span class="pre">PyRun_SimpleString()</span></code></a>,它接受单个字符串参数用于在模块 <code class="docutils literal notranslate"><span class="pre">__main__</span></code> 的上下文中执行并在成功时返回 <code class="docutils literal notranslate"><span class="pre">0</span></code> 而在发生异常 (包括 <a class="reference internal" href="../library/exceptions.html#SyntaxError" title="SyntaxError"><code class="xref py py-exc docutils literal notranslate"><span class="pre">SyntaxError</span></code></a>) 时返回 <code class="docutils literal notranslate"><span class="pre">-1</span></code>。 如果你想要更多可控性,可以使用 <a class="reference internal" href="../c-api/veryhigh.html#c.PyRun_String" title="PyRun_String"><code class="xref c c-func docutils literal notranslate"><span class="pre">PyRun_String()</span></code></a>;请在 <code class="docutils literal notranslate"><span class="pre">Python/pythonrun.c</span></code> 中查看 <a class="reference internal" href="../c-api/veryhigh.html#c.PyRun_SimpleString" title="PyRun_SimpleString"><code class="xref c c-func docutils literal notranslate"><span class="pre">PyRun_SimpleString()</span></code></a> 的源码。</p>
|
||||
</section>
|
||||
<section id="how-can-i-evaluate-an-arbitrary-python-expression-from-c">
|
||||
<h2><a class="toc-backref" href="#id8">如何在 C 中对任意 Python 表达式求值?</a><a class="headerlink" href="#how-can-i-evaluate-an-arbitrary-python-expression-from-c" title="永久链接至标题">¶</a></h2>
|
||||
<p>可以调用前一问题中介绍的函数 <a class="reference internal" href="../c-api/veryhigh.html#c.PyRun_String" title="PyRun_String"><code class="xref c c-func docutils literal notranslate"><span class="pre">PyRun_String()</span></code></a> 并附带起始标记符 <a class="reference internal" href="../c-api/veryhigh.html#c.Py_eval_input" title="Py_eval_input"><code class="xref c c-data docutils literal notranslate"><span class="pre">Py_eval_input</span></code></a>;它会解析表达式,对其求值并返回结果值。</p>
|
||||
</section>
|
||||
<section id="how-do-i-extract-c-values-from-a-python-object">
|
||||
<h2><a class="toc-backref" href="#id9">如何从Python对象中提取C的值?</a><a class="headerlink" href="#how-do-i-extract-c-values-from-a-python-object" title="永久链接至标题">¶</a></h2>
|
||||
<p>这取决于对象的类型。 如果是元组,<a class="reference internal" href="../c-api/tuple.html#c.PyTuple_Size" title="PyTuple_Size"><code class="xref c c-func docutils literal notranslate"><span class="pre">PyTuple_Size()</span></code></a> 可返回其长度而 <a class="reference internal" href="../c-api/tuple.html#c.PyTuple_GetItem" title="PyTuple_GetItem"><code class="xref c c-func docutils literal notranslate"><span class="pre">PyTuple_GetItem()</span></code></a> 可返回指定序号上的项。 对于列表也有类似的函数 <code class="xref c c-func docutils literal notranslate"><span class="pre">PyListSize()</span></code> 和 <a class="reference internal" href="../c-api/list.html#c.PyList_GetItem" title="PyList_GetItem"><code class="xref c c-func docutils literal notranslate"><span class="pre">PyList_GetItem()</span></code></a>。</p>
|
||||
<p>对于字节串,<a class="reference internal" href="../c-api/bytes.html#c.PyBytes_Size" title="PyBytes_Size"><code class="xref c c-func docutils literal notranslate"><span class="pre">PyBytes_Size()</span></code></a> 可返回其长度而 <a class="reference internal" href="../c-api/bytes.html#c.PyBytes_AsStringAndSize" title="PyBytes_AsStringAndSize"><code class="xref c c-func docutils literal notranslate"><span class="pre">PyBytes_AsStringAndSize()</span></code></a> 提供一个指向其值和长度的指针。 请注意 Python 字节串可能为空,因此 C 的 <code class="xref c c-func docutils literal notranslate"><span class="pre">strlen()</span></code> 不应被使用。</p>
|
||||
<p>要检测一个对象的类型,首先要确保它不为 <code class="docutils literal notranslate"><span class="pre">NULL</span></code>,然后使用 <a class="reference internal" href="../c-api/bytes.html#c.PyBytes_Check" title="PyBytes_Check"><code class="xref c c-func docutils literal notranslate"><span class="pre">PyBytes_Check()</span></code></a>, <a class="reference internal" href="../c-api/tuple.html#c.PyTuple_Check" title="PyTuple_Check"><code class="xref c c-func docutils literal notranslate"><span class="pre">PyTuple_Check()</span></code></a>, <a class="reference internal" href="../c-api/list.html#c.PyList_Check" title="PyList_Check"><code class="xref c c-func docutils literal notranslate"><span class="pre">PyList_Check()</span></code></a> 等等。</p>
|
||||
<p>还有一个针对 Python 对象的高层级 API,通过所谓的‘抽象’接口提供 —— 请参阅 <code class="docutils literal notranslate"><span class="pre">Include/abstract.h</span></code> 了解详情。 它允许使用 <a class="reference internal" href="../c-api/sequence.html#c.PySequence_Length" title="PySequence_Length"><code class="xref c c-func docutils literal notranslate"><span class="pre">PySequence_Length()</span></code></a>, <a class="reference internal" href="../c-api/sequence.html#c.PySequence_GetItem" title="PySequence_GetItem"><code class="xref c c-func docutils literal notranslate"><span class="pre">PySequence_GetItem()</span></code></a> 这样的调用来与任意种类的 Python 序列进行对接,此外还可使用许多其他有用的协议例如数字 (<a class="reference internal" href="../c-api/number.html#c.PyNumber_Index" title="PyNumber_Index"><code class="xref c c-func docutils literal notranslate"><span class="pre">PyNumber_Index()</span></code></a> 等) 以及 PyMapping API 中的各种映射等等。</p>
|
||||
</section>
|
||||
<section id="how-do-i-use-py-buildvalue-to-create-a-tuple-of-arbitrary-length">
|
||||
<h2><a class="toc-backref" href="#id10">如何使用Py_BuildValue()创建任意长度的元组?</a><a class="headerlink" href="#how-do-i-use-py-buildvalue-to-create-a-tuple-of-arbitrary-length" title="永久链接至标题">¶</a></h2>
|
||||
<p>不可以。应该使用 <a class="reference internal" href="../c-api/tuple.html#c.PyTuple_Pack" title="PyTuple_Pack"><code class="xref c c-func docutils literal notranslate"><span class="pre">PyTuple_Pack()</span></code></a> 。</p>
|
||||
</section>
|
||||
<section id="how-do-i-call-an-object-s-method-from-c">
|
||||
<h2><a class="toc-backref" href="#id11">如何从C调用对象的方法?</a><a class="headerlink" href="#how-do-i-call-an-object-s-method-from-c" title="永久链接至标题">¶</a></h2>
|
||||
<p>可以使用 <a class="reference internal" href="../c-api/object.html#c.PyObject_CallMethod" title="PyObject_CallMethod"><code class="xref c c-func docutils literal notranslate"><span class="pre">PyObject_CallMethod()</span></code></a> 函数来调用某个对象的任意方法。 形参为该对象、要调用的方法名、类似 <a class="reference internal" href="../c-api/arg.html#c.Py_BuildValue" title="Py_BuildValue"><code class="xref c c-func docutils literal notranslate"><span class="pre">Py_BuildValue()</span></code></a> 所用的格式字符串以及要传给方法的参数值:</p>
|
||||
<div class="highlight-c notranslate"><div class="highlight"><pre><span></span><span class="n">PyObject</span><span class="w"> </span><span class="o">*</span>
|
||||
<span class="nf">PyObject_CallMethod</span><span class="p">(</span><span class="n">PyObject</span><span class="w"> </span><span class="o">*</span><span class="n">object</span><span class="p">,</span><span class="w"> </span><span class="k">const</span><span class="w"> </span><span class="kt">char</span><span class="w"> </span><span class="o">*</span><span class="n">method_name</span><span class="p">,</span>
|
||||
<span class="w"> </span><span class="k">const</span><span class="w"> </span><span class="kt">char</span><span class="w"> </span><span class="o">*</span><span class="n">arg_format</span><span class="p">,</span><span class="w"> </span><span class="p">...);</span>
|
||||
</pre></div>
|
||||
</div>
|
||||
<p>这适用于任何具有方法的对象 —— 不论是内置方法还是用户自定义方法。 你需要负责对返回值进行最终的 <a class="reference internal" href="../c-api/refcounting.html#c.Py_DECREF" title="Py_DECREF"><code class="xref c c-func docutils literal notranslate"><span class="pre">Py_DECREF()</span></code></a> 处理。</p>
|
||||
<p>例如调用某个文件对象的 "seek" 方法并传入参数 10, 0 (假定文件对象的指针为 "f"):</p>
|
||||
<div class="highlight-c notranslate"><div class="highlight"><pre><span></span><span class="n">res</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">PyObject_CallMethod</span><span class="p">(</span><span class="n">f</span><span class="p">,</span><span class="w"> </span><span class="s">"seek"</span><span class="p">,</span><span class="w"> </span><span class="s">"(ii)"</span><span class="p">,</span><span class="w"> </span><span class="mi">10</span><span class="p">,</span><span class="w"> </span><span class="mi">0</span><span class="p">);</span>
|
||||
<span class="k">if</span><span class="w"> </span><span class="p">(</span><span class="n">res</span><span class="w"> </span><span class="o">==</span><span class="w"> </span><span class="nb">NULL</span><span class="p">)</span><span class="w"> </span><span class="p">{</span>
|
||||
<span class="w"> </span><span class="p">...</span><span class="w"> </span><span class="n">an</span><span class="w"> </span><span class="n">exception</span><span class="w"> </span><span class="n">occurred</span><span class="w"> </span><span class="p">...</span>
|
||||
<span class="p">}</span>
|
||||
<span class="k">else</span><span class="w"> </span><span class="p">{</span>
|
||||
<span class="w"> </span><span class="n">Py_DECREF</span><span class="p">(</span><span class="n">res</span><span class="p">);</span>
|
||||
<span class="p">}</span>
|
||||
</pre></div>
|
||||
</div>
|
||||
<p>请注意由于 <a class="reference internal" href="../c-api/object.html#c.PyObject_CallObject" title="PyObject_CallObject"><code class="xref c c-func docutils literal notranslate"><span class="pre">PyObject_CallObject()</span></code></a> <em>总是</em> 接受一个元组作为参数列表,要调用不带参数的函数,则传入格式为 "()",要调用只带一个参数的函数,则应将参数包含于圆括号中,例如 "(i)"。</p>
|
||||
</section>
|
||||
<section id="how-do-i-catch-the-output-from-pyerr-print-or-anything-that-prints-to-stdout-stderr">
|
||||
<h2><a class="toc-backref" href="#id12">如何捕获PyErr_Print()(或打印到stdout / stderr的任何内容)的输出?</a><a class="headerlink" href="#how-do-i-catch-the-output-from-pyerr-print-or-anything-that-prints-to-stdout-stderr" title="永久链接至标题">¶</a></h2>
|
||||
<p>在 Python 代码中,定义一个支持 <code class="docutils literal notranslate"><span class="pre">write()</span></code> 方法的对象。 将此对象赋值给 <a class="reference internal" href="../library/sys.html#sys.stdout" title="sys.stdout"><code class="xref py py-data docutils literal notranslate"><span class="pre">sys.stdout</span></code></a> 和 <a class="reference internal" href="../library/sys.html#sys.stderr" title="sys.stderr"><code class="xref py py-data docutils literal notranslate"><span class="pre">sys.stderr</span></code></a>。 调用 print_error 或者只是允许标准回溯机制生效。 在此之后,输出将转往你的 <code class="docutils literal notranslate"><span class="pre">write()</span></code> 方法所指向的任何地方。</p>
|
||||
<p>做到这一点的最简单方式是使用 <a class="reference internal" href="../library/io.html#io.StringIO" title="io.StringIO"><code class="xref py py-class docutils literal notranslate"><span class="pre">io.StringIO</span></code></a> 类:</p>
|
||||
<div class="highlight-pycon notranslate"><div class="highlight"><pre><span></span><span class="gp">>>> </span><span class="kn">import</span> <span class="nn">io</span><span class="o">,</span> <span class="nn">sys</span>
|
||||
<span class="gp">>>> </span><span class="n">sys</span><span class="o">.</span><span class="n">stdout</span> <span class="o">=</span> <span class="n">io</span><span class="o">.</span><span class="n">StringIO</span><span class="p">()</span>
|
||||
<span class="gp">>>> </span><span class="nb">print</span><span class="p">(</span><span class="s1">'foo'</span><span class="p">)</span>
|
||||
<span class="gp">>>> </span><span class="nb">print</span><span class="p">(</span><span class="s1">'hello world!'</span><span class="p">)</span>
|
||||
<span class="gp">>>> </span><span class="n">sys</span><span class="o">.</span><span class="n">stderr</span><span class="o">.</span><span class="n">write</span><span class="p">(</span><span class="n">sys</span><span class="o">.</span><span class="n">stdout</span><span class="o">.</span><span class="n">getvalue</span><span class="p">())</span>
|
||||
<span class="go">foo</span>
|
||||
<span class="go">hello world!</span>
|
||||
</pre></div>
|
||||
</div>
|
||||
<p>实现同样效果的自定义对象看起来是这样的:</p>
|
||||
<div class="highlight-pycon notranslate"><div class="highlight"><pre><span></span><span class="gp">>>> </span><span class="kn">import</span> <span class="nn">io</span><span class="o">,</span> <span class="nn">sys</span>
|
||||
<span class="gp">>>> </span><span class="k">class</span> <span class="nc">StdoutCatcher</span><span class="p">(</span><span class="n">io</span><span class="o">.</span><span class="n">TextIOBase</span><span class="p">):</span>
|
||||
<span class="gp">... </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="gp">... </span> <span class="bp">self</span><span class="o">.</span><span class="n">data</span> <span class="o">=</span> <span class="p">[]</span>
|
||||
<span class="gp">... </span> <span class="k">def</span> <span class="nf">write</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">stuff</span><span class="p">):</span>
|
||||
<span class="gp">... </span> <span class="bp">self</span><span class="o">.</span><span class="n">data</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">stuff</span><span class="p">)</span>
|
||||
<span class="gp">...</span>
|
||||
<span class="gp">>>> </span><span class="kn">import</span> <span class="nn">sys</span>
|
||||
<span class="gp">>>> </span><span class="n">sys</span><span class="o">.</span><span class="n">stdout</span> <span class="o">=</span> <span class="n">StdoutCatcher</span><span class="p">()</span>
|
||||
<span class="gp">>>> </span><span class="nb">print</span><span class="p">(</span><span class="s1">'foo'</span><span class="p">)</span>
|
||||
<span class="gp">>>> </span><span class="nb">print</span><span class="p">(</span><span class="s1">'hello world!'</span><span class="p">)</span>
|
||||
<span class="gp">>>> </span><span class="n">sys</span><span class="o">.</span><span class="n">stderr</span><span class="o">.</span><span class="n">write</span><span class="p">(</span><span class="s1">''</span><span class="o">.</span><span class="n">join</span><span class="p">(</span><span class="n">sys</span><span class="o">.</span><span class="n">stdout</span><span class="o">.</span><span class="n">data</span><span class="p">))</span>
|
||||
<span class="go">foo</span>
|
||||
<span class="go">hello world!</span>
|
||||
</pre></div>
|
||||
</div>
|
||||
</section>
|
||||
<section id="how-do-i-access-a-module-written-in-python-from-c">
|
||||
<h2><a class="toc-backref" href="#id13">如何从C访问用Python编写的模块?</a><a class="headerlink" href="#how-do-i-access-a-module-written-in-python-from-c" title="永久链接至标题">¶</a></h2>
|
||||
<p>你可以通过如下方式获得一个指向模块对象的指针:</p>
|
||||
<div class="highlight-c notranslate"><div class="highlight"><pre><span></span><span class="n">module</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">PyImport_ImportModule</span><span class="p">(</span><span class="s">"<modulename>"</span><span class="p">);</span>
|
||||
</pre></div>
|
||||
</div>
|
||||
<p>如果模块尚未被导入(即它还不存在于 <a class="reference internal" href="../library/sys.html#sys.modules" title="sys.modules"><code class="xref py py-data docutils literal notranslate"><span class="pre">sys.modules</span></code></a> 中),这会初始化该模块;否则它只是简单地返回 <code class="docutils literal notranslate"><span class="pre">sys.modules["<modulename>"]</span></code> 的值。 请注意它并不会将模块加入任何命名空间 —— 它只是确保模块被初始化并存在于 <a class="reference internal" href="../library/sys.html#sys.modules" title="sys.modules"><code class="xref py py-data docutils literal notranslate"><span class="pre">sys.modules</span></code></a> 中。</p>
|
||||
<p>之后你就可以通过如下方式来访问模块的属性(即模块中定义的任何名称):</p>
|
||||
<div class="highlight-c notranslate"><div class="highlight"><pre><span></span><span class="n">attr</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">PyObject_GetAttrString</span><span class="p">(</span><span class="n">module</span><span class="p">,</span><span class="w"> </span><span class="s">"<attrname>"</span><span class="p">);</span>
|
||||
</pre></div>
|
||||
</div>
|
||||
<p>调用 <a class="reference internal" href="../c-api/object.html#c.PyObject_SetAttrString" title="PyObject_SetAttrString"><code class="xref c c-func docutils literal notranslate"><span class="pre">PyObject_SetAttrString()</span></code></a> 为模块中的变量赋值也是可以的。</p>
|
||||
</section>
|
||||
<section id="how-do-i-interface-to-c-objects-from-python">
|
||||
<h2><a class="toc-backref" href="#id14">如何在 Python 中对接 C ++ 对象?</a><a class="headerlink" href="#how-do-i-interface-to-c-objects-from-python" title="永久链接至标题">¶</a></h2>
|
||||
<p>根据你的需求,可以选择许多方式。 手动的实现方式请查阅 <a class="reference internal" href="../extending/index.html#extending-index"><span class="std std-ref">"扩展与嵌入" 文档</span></a> 来入门。 需要知道的是对于 Python 运行时系统来说,C 和 C++ 并不没有太大的区别 —— 因此围绕一个 C 结构(指针)类型构建新 Python 对象的策略同样适用于 C++ 对象。</p>
|
||||
<p>有关C ++库,请参阅 <a class="reference internal" href="#c-wrapper-software"><span class="std std-ref">C很难写,有没有其他选择?</span></a></p>
|
||||
</section>
|
||||
<section id="i-added-a-module-using-the-setup-file-and-the-make-fails-why">
|
||||
<h2><a class="toc-backref" href="#id15">我使用Setup文件添加了一个模块,为什么make失败了?</a><a class="headerlink" href="#i-added-a-module-using-the-setup-file-and-the-make-fails-why" title="永久链接至标题">¶</a></h2>
|
||||
<p>安装程序必须以换行符结束,如果没有换行符,则构建过程将失败。 (修复这个需要一些丑陋的shell脚本编程,而且这个bug很小,看起来不值得花这么大力气。)</p>
|
||||
</section>
|
||||
<section id="how-do-i-debug-an-extension">
|
||||
<h2><a class="toc-backref" href="#id16">如何调试扩展?</a><a class="headerlink" href="#how-do-i-debug-an-extension" title="永久链接至标题">¶</a></h2>
|
||||
<p>将GDB与动态加载的扩展名一起使用时,在加载扩展名之前,不能在扩展名中设置断点。</p>
|
||||
<p>在您的 <code class="docutils literal notranslate"><span class="pre">.gdbinit</span></code> 文件中(或交互式)添加命令:</p>
|
||||
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>br _PyImport_LoadDynamicModule
|
||||
</pre></div>
|
||||
</div>
|
||||
<p>然后运行GDB:</p>
|
||||
<div class="highlight-shell-session notranslate"><div class="highlight"><pre><span></span><span class="gp">$ </span>gdb<span class="w"> </span>/local/bin/python
|
||||
<span class="go">gdb) run myscript.py</span>
|
||||
<span class="go">gdb) continue # repeat until your extension is loaded</span>
|
||||
<span class="go">gdb) finish # so that your extension is loaded</span>
|
||||
<span class="go">gdb) br myfunction.c:50</span>
|
||||
<span class="go">gdb) continue</span>
|
||||
</pre></div>
|
||||
</div>
|
||||
</section>
|
||||
<section id="i-want-to-compile-a-python-module-on-my-linux-system-but-some-files-are-missing-why">
|
||||
<h2><a class="toc-backref" href="#id17">我想在Linux系统上编译一个Python模块,但是缺少一些文件。为什么?</a><a class="headerlink" href="#i-want-to-compile-a-python-module-on-my-linux-system-but-some-files-are-missing-why" title="永久链接至标题">¶</a></h2>
|
||||
<p>大多数打包的Python版本不包含 <code class="file docutils literal notranslate"><span class="pre">/usr/lib/python2.</span><em><span class="pre">x</span></em><span class="pre">/config/</span></code> 目录,该目录中包含编译Python扩展所需的各种文件。</p>
|
||||
<p>对于Red Hat,安装python-devel RPM以获取必要的文件。</p>
|
||||
<p>对于Debian,运行 <code class="docutils literal notranslate"><span class="pre">apt-get</span> <span class="pre">install</span> <span class="pre">python-dev</span></code> 。</p>
|
||||
</section>
|
||||
<section id="how-do-i-tell-incomplete-input-from-invalid-input">
|
||||
<h2><a class="toc-backref" href="#id18">如何区分“输入不完整”和“输入无效”?</a><a class="headerlink" href="#how-do-i-tell-incomplete-input-from-invalid-input" title="永久链接至标题">¶</a></h2>
|
||||
<p>有时,希望模仿Python交互式解释器的行为,在输入不完整时(例如,您键入了“if”语句的开头,或者没有关闭括号或三个字符串引号),给出一个延续提示,但当输入无效时,立即给出一条语法错误消息。</p>
|
||||
<p>在Python中,您可以使用 <a class="reference internal" href="../library/codeop.html#module-codeop" title="codeop: Compile (possibly incomplete) Python code."><code class="xref py py-mod docutils literal notranslate"><span class="pre">codeop</span></code></a> 模块,该模块非常接近解析器的行为。例如,IDLE就使用了这个。</p>
|
||||
<p>在C中执行此操作的最简单方法是调用 <a class="reference internal" href="../c-api/veryhigh.html#c.PyRun_InteractiveLoop" title="PyRun_InteractiveLoop"><code class="xref c c-func docutils literal notranslate"><span class="pre">PyRun_InteractiveLoop()</span></code></a> (可能在单独的线程中)并让Python解释器为您处理输入。您还可以设置 <a class="reference internal" href="../c-api/veryhigh.html#c.PyOS_ReadlineFunctionPointer" title="PyOS_ReadlineFunctionPointer"><code class="xref c c-func docutils literal notranslate"><span class="pre">PyOS_ReadlineFunctionPointer()</span></code></a> 指向您的自定义输入函数。有关更多提示,请参阅 <code class="docutils literal notranslate"><span class="pre">Modules/readline.c</span></code> 和 <code class="docutils literal notranslate"><span class="pre">Parser/myreadline.c</span></code> 。</p>
|
||||
<p>但是,有时必须在与其他应用程序相同的线程中运行嵌入式Python解释器,并且不能允许 <a class="reference internal" href="../c-api/veryhigh.html#c.PyRun_InteractiveLoop" title="PyRun_InteractiveLoop"><code class="xref c c-func docutils literal notranslate"><span class="pre">PyRun_InteractiveLoop()</span></code></a> 在等待用户输入时停止。那么另一个解决方案是调用 <code class="xref c c-func docutils literal notranslate"><span class="pre">PyParser_ParseString()</span></code> 并测试 <code class="docutils literal notranslate"><span class="pre">e.error</span></code> 等于 <code class="docutils literal notranslate"><span class="pre">E_EOF</span></code> ,如果等于,就意味着输入不完整。这是一个示例代码片段,未经测试,灵感来自Alex Farber的代码:</p>
|
||||
<div class="highlight-c notranslate"><div class="highlight"><pre><span></span><span class="cp">#define PY_SSIZE_T_CLEAN</span>
|
||||
<span class="cp">#include</span><span class="w"> </span><span class="cpf"><Python.h></span>
|
||||
<span class="cp">#include</span><span class="w"> </span><span class="cpf"><node.h></span>
|
||||
<span class="cp">#include</span><span class="w"> </span><span class="cpf"><errcode.h></span>
|
||||
<span class="cp">#include</span><span class="w"> </span><span class="cpf"><grammar.h></span>
|
||||
<span class="cp">#include</span><span class="w"> </span><span class="cpf"><parsetok.h></span>
|
||||
<span class="cp">#include</span><span class="w"> </span><span class="cpf"><compile.h></span>
|
||||
|
||||
<span class="kt">int</span><span class="w"> </span><span class="nf">testcomplete</span><span class="p">(</span><span class="kt">char</span><span class="w"> </span><span class="o">*</span><span class="n">code</span><span class="p">)</span>
|
||||
<span class="w"> </span><span class="cm">/* code should end in \n */</span>
|
||||
<span class="w"> </span><span class="cm">/* return -1 for error, 0 for incomplete, 1 for complete */</span>
|
||||
<span class="p">{</span>
|
||||
<span class="w"> </span><span class="n">node</span><span class="w"> </span><span class="o">*</span><span class="n">n</span><span class="p">;</span>
|
||||
<span class="w"> </span><span class="n">perrdetail</span><span class="w"> </span><span class="n">e</span><span class="p">;</span>
|
||||
|
||||
<span class="w"> </span><span class="n">n</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">PyParser_ParseString</span><span class="p">(</span><span class="n">code</span><span class="p">,</span><span class="w"> </span><span class="o">&</span><span class="n">_PyParser_Grammar</span><span class="p">,</span>
|
||||
<span class="w"> </span><span class="n">Py_file_input</span><span class="p">,</span><span class="w"> </span><span class="o">&</span><span class="n">e</span><span class="p">);</span>
|
||||
<span class="w"> </span><span class="k">if</span><span class="w"> </span><span class="p">(</span><span class="n">n</span><span class="w"> </span><span class="o">==</span><span class="w"> </span><span class="nb">NULL</span><span class="p">)</span><span class="w"> </span><span class="p">{</span>
|
||||
<span class="w"> </span><span class="k">if</span><span class="w"> </span><span class="p">(</span><span class="n">e</span><span class="p">.</span><span class="n">error</span><span class="w"> </span><span class="o">==</span><span class="w"> </span><span class="n">E_EOF</span><span class="p">)</span>
|
||||
<span class="w"> </span><span class="k">return</span><span class="w"> </span><span class="mi">0</span><span class="p">;</span>
|
||||
<span class="w"> </span><span class="k">return</span><span class="w"> </span><span class="mi">-1</span><span class="p">;</span>
|
||||
<span class="w"> </span><span class="p">}</span>
|
||||
|
||||
<span class="w"> </span><span class="n">PyNode_Free</span><span class="p">(</span><span class="n">n</span><span class="p">);</span>
|
||||
<span class="w"> </span><span class="k">return</span><span class="w"> </span><span class="mi">1</span><span class="p">;</span>
|
||||
<span class="p">}</span>
|
||||
</pre></div>
|
||||
</div>
|
||||
<p>另一个解决方案是尝试使用 <a class="reference internal" href="../c-api/veryhigh.html#c.Py_CompileString" title="Py_CompileString"><code class="xref c c-func docutils literal notranslate"><span class="pre">Py_CompileString()</span></code></a> 编译接收到的字符串。如果编译时没有出现错误,请尝试通过调用 <a class="reference internal" href="../c-api/veryhigh.html#c.PyEval_EvalCode" title="PyEval_EvalCode"><code class="xref c c-func docutils literal notranslate"><span class="pre">PyEval_EvalCode()</span></code></a> 来执行返回的代码对象。否则,请将输入保存到以后。如果编译失败,找出是错误还是只需要更多的输入-从异常元组中提取消息字符串,并将其与字符串 “分析时意外的EOF” 进行比较。下面是使用GNUreadline库的完整示例(您可能希望在调用readline()时忽略 <strong>SIGINT</strong> ):</p>
|
||||
<div class="highlight-c notranslate"><div class="highlight"><pre><span></span><span class="cp">#include</span><span class="w"> </span><span class="cpf"><stdio.h></span>
|
||||
<span class="cp">#include</span><span class="w"> </span><span class="cpf"><readline.h></span>
|
||||
|
||||
<span class="cp">#define PY_SSIZE_T_CLEAN</span>
|
||||
<span class="cp">#include</span><span class="w"> </span><span class="cpf"><Python.h></span>
|
||||
<span class="cp">#include</span><span class="w"> </span><span class="cpf"><object.h></span>
|
||||
<span class="cp">#include</span><span class="w"> </span><span class="cpf"><compile.h></span>
|
||||
<span class="cp">#include</span><span class="w"> </span><span class="cpf"><eval.h></span>
|
||||
|
||||
<span class="kt">int</span><span class="w"> </span><span class="nf">main</span><span class="w"> </span><span class="p">(</span><span class="kt">int</span><span class="w"> </span><span class="n">argc</span><span class="p">,</span><span class="w"> </span><span class="kt">char</span><span class="o">*</span><span class="w"> </span><span class="n">argv</span><span class="p">[])</span>
|
||||
<span class="p">{</span>
|
||||
<span class="w"> </span><span class="kt">int</span><span class="w"> </span><span class="n">i</span><span class="p">,</span><span class="w"> </span><span class="n">j</span><span class="p">,</span><span class="w"> </span><span class="n">done</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="mi">0</span><span class="p">;</span><span class="w"> </span><span class="cm">/* lengths of line, code */</span>
|
||||
<span class="w"> </span><span class="kt">char</span><span class="w"> </span><span class="n">ps1</span><span class="p">[]</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="s">">>> "</span><span class="p">;</span>
|
||||
<span class="w"> </span><span class="kt">char</span><span class="w"> </span><span class="n">ps2</span><span class="p">[]</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="s">"... "</span><span class="p">;</span>
|
||||
<span class="w"> </span><span class="kt">char</span><span class="w"> </span><span class="o">*</span><span class="n">prompt</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">ps1</span><span class="p">;</span>
|
||||
<span class="w"> </span><span class="kt">char</span><span class="w"> </span><span class="o">*</span><span class="n">msg</span><span class="p">,</span><span class="w"> </span><span class="o">*</span><span class="n">line</span><span class="p">,</span><span class="w"> </span><span class="o">*</span><span class="n">code</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="nb">NULL</span><span class="p">;</span>
|
||||
<span class="w"> </span><span class="n">PyObject</span><span class="w"> </span><span class="o">*</span><span class="n">src</span><span class="p">,</span><span class="w"> </span><span class="o">*</span><span class="n">glb</span><span class="p">,</span><span class="w"> </span><span class="o">*</span><span class="n">loc</span><span class="p">;</span>
|
||||
<span class="w"> </span><span class="n">PyObject</span><span class="w"> </span><span class="o">*</span><span class="n">exc</span><span class="p">,</span><span class="w"> </span><span class="o">*</span><span class="n">val</span><span class="p">,</span><span class="w"> </span><span class="o">*</span><span class="n">trb</span><span class="p">,</span><span class="w"> </span><span class="o">*</span><span class="n">obj</span><span class="p">,</span><span class="w"> </span><span class="o">*</span><span class="n">dum</span><span class="p">;</span>
|
||||
|
||||
<span class="w"> </span><span class="n">Py_Initialize</span><span class="w"> </span><span class="p">();</span>
|
||||
<span class="w"> </span><span class="n">loc</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">PyDict_New</span><span class="w"> </span><span class="p">();</span>
|
||||
<span class="w"> </span><span class="n">glb</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">PyDict_New</span><span class="w"> </span><span class="p">();</span>
|
||||
<span class="w"> </span><span class="n">PyDict_SetItemString</span><span class="w"> </span><span class="p">(</span><span class="n">glb</span><span class="p">,</span><span class="w"> </span><span class="s">"__builtins__"</span><span class="p">,</span><span class="w"> </span><span class="n">PyEval_GetBuiltins</span><span class="w"> </span><span class="p">());</span>
|
||||
|
||||
<span class="w"> </span><span class="k">while</span><span class="w"> </span><span class="p">(</span><span class="o">!</span><span class="n">done</span><span class="p">)</span>
|
||||
<span class="w"> </span><span class="p">{</span>
|
||||
<span class="w"> </span><span class="n">line</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">readline</span><span class="w"> </span><span class="p">(</span><span class="n">prompt</span><span class="p">);</span>
|
||||
|
||||
<span class="w"> </span><span class="k">if</span><span class="w"> </span><span class="p">(</span><span class="nb">NULL</span><span class="w"> </span><span class="o">==</span><span class="w"> </span><span class="n">line</span><span class="p">)</span><span class="w"> </span><span class="cm">/* Ctrl-D pressed */</span>
|
||||
<span class="w"> </span><span class="p">{</span>
|
||||
<span class="w"> </span><span class="n">done</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="mi">1</span><span class="p">;</span>
|
||||
<span class="w"> </span><span class="p">}</span>
|
||||
<span class="w"> </span><span class="k">else</span>
|
||||
<span class="w"> </span><span class="p">{</span>
|
||||
<span class="w"> </span><span class="n">i</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">strlen</span><span class="w"> </span><span class="p">(</span><span class="n">line</span><span class="p">);</span>
|
||||
|
||||
<span class="w"> </span><span class="k">if</span><span class="w"> </span><span class="p">(</span><span class="n">i</span><span class="w"> </span><span class="o">></span><span class="w"> </span><span class="mi">0</span><span class="p">)</span>
|
||||
<span class="w"> </span><span class="n">add_history</span><span class="w"> </span><span class="p">(</span><span class="n">line</span><span class="p">);</span><span class="w"> </span><span class="cm">/* save non-empty lines */</span>
|
||||
|
||||
<span class="w"> </span><span class="k">if</span><span class="w"> </span><span class="p">(</span><span class="nb">NULL</span><span class="w"> </span><span class="o">==</span><span class="w"> </span><span class="n">code</span><span class="p">)</span><span class="w"> </span><span class="cm">/* nothing in code yet */</span>
|
||||
<span class="w"> </span><span class="n">j</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="mi">0</span><span class="p">;</span>
|
||||
<span class="w"> </span><span class="k">else</span>
|
||||
<span class="w"> </span><span class="n">j</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">strlen</span><span class="w"> </span><span class="p">(</span><span class="n">code</span><span class="p">);</span>
|
||||
|
||||
<span class="w"> </span><span class="n">code</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">realloc</span><span class="w"> </span><span class="p">(</span><span class="n">code</span><span class="p">,</span><span class="w"> </span><span class="n">i</span><span class="w"> </span><span class="o">+</span><span class="w"> </span><span class="n">j</span><span class="w"> </span><span class="o">+</span><span class="w"> </span><span class="mi">2</span><span class="p">);</span>
|
||||
<span class="w"> </span><span class="k">if</span><span class="w"> </span><span class="p">(</span><span class="nb">NULL</span><span class="w"> </span><span class="o">==</span><span class="w"> </span><span class="n">code</span><span class="p">)</span><span class="w"> </span><span class="cm">/* out of memory */</span>
|
||||
<span class="w"> </span><span class="n">exit</span><span class="w"> </span><span class="p">(</span><span class="mi">1</span><span class="p">);</span>
|
||||
|
||||
<span class="w"> </span><span class="k">if</span><span class="w"> </span><span class="p">(</span><span class="mi">0</span><span class="w"> </span><span class="o">==</span><span class="w"> </span><span class="n">j</span><span class="p">)</span><span class="w"> </span><span class="cm">/* code was empty, so */</span>
|
||||
<span class="w"> </span><span class="n">code</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="sc">'\0'</span><span class="p">;</span><span class="w"> </span><span class="cm">/* keep strncat happy */</span>
|
||||
|
||||
<span class="w"> </span><span class="n">strncat</span><span class="w"> </span><span class="p">(</span><span class="n">code</span><span class="p">,</span><span class="w"> </span><span class="n">line</span><span class="p">,</span><span class="w"> </span><span class="n">i</span><span class="p">);</span><span class="w"> </span><span class="cm">/* append line to code */</span>
|
||||
<span class="w"> </span><span class="n">code</span><span class="p">[</span><span class="n">i</span><span class="w"> </span><span class="o">+</span><span class="w"> </span><span class="n">j</span><span class="p">]</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="sc">'\n'</span><span class="p">;</span><span class="w"> </span><span class="cm">/* append '\n' to code */</span>
|
||||
<span class="w"> </span><span class="n">code</span><span class="p">[</span><span class="n">i</span><span class="w"> </span><span class="o">+</span><span class="w"> </span><span class="n">j</span><span class="w"> </span><span class="o">+</span><span class="w"> </span><span class="mi">1</span><span class="p">]</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="sc">'\0'</span><span class="p">;</span>
|
||||
|
||||
<span class="w"> </span><span class="n">src</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">Py_CompileString</span><span class="w"> </span><span class="p">(</span><span class="n">code</span><span class="p">,</span><span class="w"> </span><span class="s">"<stdin>"</span><span class="p">,</span><span class="w"> </span><span class="n">Py_single_input</span><span class="p">);</span>
|
||||
|
||||
<span class="w"> </span><span class="k">if</span><span class="w"> </span><span class="p">(</span><span class="nb">NULL</span><span class="w"> </span><span class="o">!=</span><span class="w"> </span><span class="n">src</span><span class="p">)</span><span class="w"> </span><span class="cm">/* compiled just fine - */</span>
|
||||
<span class="w"> </span><span class="p">{</span>
|
||||
<span class="w"> </span><span class="k">if</span><span class="w"> </span><span class="p">(</span><span class="n">ps1</span><span class="w"> </span><span class="o">==</span><span class="w"> </span><span class="n">prompt</span><span class="w"> </span><span class="o">||</span><span class="w"> </span><span class="cm">/* ">>> " or */</span>
|
||||
<span class="w"> </span><span class="sc">'\n'</span><span class="w"> </span><span class="o">==</span><span class="w"> </span><span class="n">code</span><span class="p">[</span><span class="n">i</span><span class="w"> </span><span class="o">+</span><span class="w"> </span><span class="n">j</span><span class="w"> </span><span class="o">-</span><span class="w"> </span><span class="mi">1</span><span class="p">])</span><span class="w"> </span><span class="cm">/* "... " and double '\n' */</span>
|
||||
<span class="w"> </span><span class="p">{</span><span class="w"> </span><span class="cm">/* so execute it */</span>
|
||||
<span class="w"> </span><span class="n">dum</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">PyEval_EvalCode</span><span class="w"> </span><span class="p">(</span><span class="n">src</span><span class="p">,</span><span class="w"> </span><span class="n">glb</span><span class="p">,</span><span class="w"> </span><span class="n">loc</span><span class="p">);</span>
|
||||
<span class="w"> </span><span class="n">Py_XDECREF</span><span class="w"> </span><span class="p">(</span><span class="n">dum</span><span class="p">);</span>
|
||||
<span class="w"> </span><span class="n">Py_XDECREF</span><span class="w"> </span><span class="p">(</span><span class="n">src</span><span class="p">);</span>
|
||||
<span class="w"> </span><span class="n">free</span><span class="w"> </span><span class="p">(</span><span class="n">code</span><span class="p">);</span>
|
||||
<span class="w"> </span><span class="n">code</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="nb">NULL</span><span class="p">;</span>
|
||||
<span class="w"> </span><span class="k">if</span><span class="w"> </span><span class="p">(</span><span class="n">PyErr_Occurred</span><span class="w"> </span><span class="p">())</span>
|
||||
<span class="w"> </span><span class="n">PyErr_Print</span><span class="w"> </span><span class="p">();</span>
|
||||
<span class="w"> </span><span class="n">prompt</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">ps1</span><span class="p">;</span>
|
||||
<span class="w"> </span><span class="p">}</span>
|
||||
<span class="w"> </span><span class="p">}</span><span class="w"> </span><span class="cm">/* syntax error or E_EOF? */</span>
|
||||
<span class="w"> </span><span class="k">else</span><span class="w"> </span><span class="k">if</span><span class="w"> </span><span class="p">(</span><span class="n">PyErr_ExceptionMatches</span><span class="w"> </span><span class="p">(</span><span class="n">PyExc_SyntaxError</span><span class="p">))</span>
|
||||
<span class="w"> </span><span class="p">{</span>
|
||||
<span class="w"> </span><span class="n">PyErr_Fetch</span><span class="w"> </span><span class="p">(</span><span class="o">&</span><span class="n">exc</span><span class="p">,</span><span class="w"> </span><span class="o">&</span><span class="n">val</span><span class="p">,</span><span class="w"> </span><span class="o">&</span><span class="n">trb</span><span class="p">);</span><span class="w"> </span><span class="cm">/* clears exception! */</span>
|
||||
|
||||
<span class="w"> </span><span class="k">if</span><span class="w"> </span><span class="p">(</span><span class="n">PyArg_ParseTuple</span><span class="w"> </span><span class="p">(</span><span class="n">val</span><span class="p">,</span><span class="w"> </span><span class="s">"sO"</span><span class="p">,</span><span class="w"> </span><span class="o">&</span><span class="n">msg</span><span class="p">,</span><span class="w"> </span><span class="o">&</span><span class="n">obj</span><span class="p">)</span><span class="w"> </span><span class="o">&&</span>
|
||||
<span class="w"> </span><span class="o">!</span><span class="n">strcmp</span><span class="w"> </span><span class="p">(</span><span class="n">msg</span><span class="p">,</span><span class="w"> </span><span class="s">"unexpected EOF while parsing"</span><span class="p">))</span><span class="w"> </span><span class="cm">/* E_EOF */</span>
|
||||
<span class="w"> </span><span class="p">{</span>
|
||||
<span class="w"> </span><span class="n">Py_XDECREF</span><span class="w"> </span><span class="p">(</span><span class="n">exc</span><span class="p">);</span>
|
||||
<span class="w"> </span><span class="n">Py_XDECREF</span><span class="w"> </span><span class="p">(</span><span class="n">val</span><span class="p">);</span>
|
||||
<span class="w"> </span><span class="n">Py_XDECREF</span><span class="w"> </span><span class="p">(</span><span class="n">trb</span><span class="p">);</span>
|
||||
<span class="w"> </span><span class="n">prompt</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">ps2</span><span class="p">;</span>
|
||||
<span class="w"> </span><span class="p">}</span>
|
||||
<span class="w"> </span><span class="k">else</span><span class="w"> </span><span class="cm">/* some other syntax error */</span>
|
||||
<span class="w"> </span><span class="p">{</span>
|
||||
<span class="w"> </span><span class="n">PyErr_Restore</span><span class="w"> </span><span class="p">(</span><span class="n">exc</span><span class="p">,</span><span class="w"> </span><span class="n">val</span><span class="p">,</span><span class="w"> </span><span class="n">trb</span><span class="p">);</span>
|
||||
<span class="w"> </span><span class="n">PyErr_Print</span><span class="w"> </span><span class="p">();</span>
|
||||
<span class="w"> </span><span class="n">free</span><span class="w"> </span><span class="p">(</span><span class="n">code</span><span class="p">);</span>
|
||||
<span class="w"> </span><span class="n">code</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="nb">NULL</span><span class="p">;</span>
|
||||
<span class="w"> </span><span class="n">prompt</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">ps1</span><span class="p">;</span>
|
||||
<span class="w"> </span><span class="p">}</span>
|
||||
<span class="w"> </span><span class="p">}</span>
|
||||
<span class="w"> </span><span class="k">else</span><span class="w"> </span><span class="cm">/* some non-syntax error */</span>
|
||||
<span class="w"> </span><span class="p">{</span>
|
||||
<span class="w"> </span><span class="n">PyErr_Print</span><span class="w"> </span><span class="p">();</span>
|
||||
<span class="w"> </span><span class="n">free</span><span class="w"> </span><span class="p">(</span><span class="n">code</span><span class="p">);</span>
|
||||
<span class="w"> </span><span class="n">code</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="nb">NULL</span><span class="p">;</span>
|
||||
<span class="w"> </span><span class="n">prompt</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">ps1</span><span class="p">;</span>
|
||||
<span class="w"> </span><span class="p">}</span>
|
||||
|
||||
<span class="w"> </span><span class="n">free</span><span class="w"> </span><span class="p">(</span><span class="n">line</span><span class="p">);</span>
|
||||
<span class="w"> </span><span class="p">}</span>
|
||||
<span class="w"> </span><span class="p">}</span>
|
||||
|
||||
<span class="w"> </span><span class="n">Py_XDECREF</span><span class="p">(</span><span class="n">glb</span><span class="p">);</span>
|
||||
<span class="w"> </span><span class="n">Py_XDECREF</span><span class="p">(</span><span class="n">loc</span><span class="p">);</span>
|
||||
<span class="w"> </span><span class="n">Py_Finalize</span><span class="p">();</span>
|
||||
<span class="w"> </span><span class="n">exit</span><span class="p">(</span><span class="mi">0</span><span class="p">);</span>
|
||||
<span class="p">}</span>
|
||||
</pre></div>
|
||||
</div>
|
||||
</section>
|
||||
<section id="how-do-i-find-undefined-g-symbols-builtin-new-or-pure-virtual">
|
||||
<h2><a class="toc-backref" href="#id19">如何找到未定义的g++符号__builtin_new或__pure_virtual?</a><a class="headerlink" href="#how-do-i-find-undefined-g-symbols-builtin-new-or-pure-virtual" title="永久链接至标题">¶</a></h2>
|
||||
<p>要动态加载g ++扩展模块,必须重新编译Python,要使用g ++重新链接(在Python Modules Makefile中更改LINKCC),及链接扩展模块(例如: <code class="docutils literal notranslate"><span class="pre">g++</span> <span class="pre">-shared</span> <span class="pre">-o</span> <span class="pre">mymodule.so</span> <span class="pre">mymodule.o</span></code> )。</p>
|
||||
</section>
|
||||
<section id="can-i-create-an-object-class-with-some-methods-implemented-in-c-and-others-in-python-e-g-through-inheritance">
|
||||
<h2><a class="toc-backref" href="#id20">能否创建一个对象类,其中部分方法在C中实现,而其他方法在Python中实现(例如通过继承)?</a><a class="headerlink" href="#can-i-create-an-object-class-with-some-methods-implemented-in-c-and-others-in-python-e-g-through-inheritance" title="永久链接至标题">¶</a></h2>
|
||||
<p>是的,您可以继承内置类,例如 <a class="reference internal" href="../library/functions.html#int" title="int"><code class="xref py py-class docutils literal notranslate"><span class="pre">int</span></code></a> , <a class="reference internal" href="../library/stdtypes.html#list" title="list"><code class="xref py py-class docutils literal notranslate"><span class="pre">list</span></code></a> , <a class="reference internal" href="../library/stdtypes.html#dict" title="dict"><code class="xref py py-class docutils literal notranslate"><span class="pre">dict</span></code></a> 等。</p>
|
||||
<p>Boost Python库(BPL,http://www.boost.org/libs/python/doc/index.html)提供了一种从C ++执行此操作的方法(即,您可以使用BPL继承自C ++编写的扩展类 )。</p>
|
||||
</section>
|
||||
</section>
|
||||
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="sphinxsidebar" role="navigation" aria-label="main navigation">
|
||||
<div class="sphinxsidebarwrapper">
|
||||
<h3><a href="../contents.html">目录</a></h3>
|
||||
<ul>
|
||||
<li><a class="reference internal" href="#">扩展/嵌入常见问题</a><ul>
|
||||
<li><a class="reference internal" href="#can-i-create-my-own-functions-in-c">可以使用 C 语言创建自己的函数吗?</a></li>
|
||||
<li><a class="reference internal" href="#id2">可以使用 C++ 语言创建自己的函数吗?</a></li>
|
||||
<li><a class="reference internal" href="#writing-c-is-hard-are-there-any-alternatives">C很难写,有没有其他选择?</a></li>
|
||||
<li><a class="reference internal" href="#how-can-i-execute-arbitrary-python-statements-from-c">如何在 C 中执行任意 Python 语句?</a></li>
|
||||
<li><a class="reference internal" href="#how-can-i-evaluate-an-arbitrary-python-expression-from-c">如何在 C 中对任意 Python 表达式求值?</a></li>
|
||||
<li><a class="reference internal" href="#how-do-i-extract-c-values-from-a-python-object">如何从Python对象中提取C的值?</a></li>
|
||||
<li><a class="reference internal" href="#how-do-i-use-py-buildvalue-to-create-a-tuple-of-arbitrary-length">如何使用Py_BuildValue()创建任意长度的元组?</a></li>
|
||||
<li><a class="reference internal" href="#how-do-i-call-an-object-s-method-from-c">如何从C调用对象的方法?</a></li>
|
||||
<li><a class="reference internal" href="#how-do-i-catch-the-output-from-pyerr-print-or-anything-that-prints-to-stdout-stderr">如何捕获PyErr_Print()(或打印到stdout / stderr的任何内容)的输出?</a></li>
|
||||
<li><a class="reference internal" href="#how-do-i-access-a-module-written-in-python-from-c">如何从C访问用Python编写的模块?</a></li>
|
||||
<li><a class="reference internal" href="#how-do-i-interface-to-c-objects-from-python">如何在 Python 中对接 C ++ 对象?</a></li>
|
||||
<li><a class="reference internal" href="#i-added-a-module-using-the-setup-file-and-the-make-fails-why">我使用Setup文件添加了一个模块,为什么make失败了?</a></li>
|
||||
<li><a class="reference internal" href="#how-do-i-debug-an-extension">如何调试扩展?</a></li>
|
||||
<li><a class="reference internal" href="#i-want-to-compile-a-python-module-on-my-linux-system-but-some-files-are-missing-why">我想在Linux系统上编译一个Python模块,但是缺少一些文件。为什么?</a></li>
|
||||
<li><a class="reference internal" href="#how-do-i-tell-incomplete-input-from-invalid-input">如何区分“输入不完整”和“输入无效”?</a></li>
|
||||
<li><a class="reference internal" href="#how-do-i-find-undefined-g-symbols-builtin-new-or-pure-virtual">如何找到未定义的g++符号__builtin_new或__pure_virtual?</a></li>
|
||||
<li><a class="reference internal" href="#can-i-create-an-object-class-with-some-methods-implemented-in-c-and-others-in-python-e-g-through-inheritance">能否创建一个对象类,其中部分方法在C中实现,而其他方法在Python中实现(例如通过继承)?</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<h4>上一个主题</h4>
|
||||
<p class="topless"><a href="library.html"
|
||||
title="上一章">代码库和插件 FAQ</a></p>
|
||||
<h4>下一个主题</h4>
|
||||
<p class="topless"><a href="windows.html"
|
||||
title="下一章">Python在Windows上的常见问题</a></p>
|
||||
<div role="note" aria-label="source link">
|
||||
<h3>本页</h3>
|
||||
<ul class="this-page-menu">
|
||||
<li><a href="../bugs.html">报告 Bug</a></li>
|
||||
<li>
|
||||
<a href="https://github.com/python/cpython/blob/3.8/Doc/faq/extending.rst"
|
||||
rel="nofollow">显示源代码
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="clearer"></div>
|
||||
</div>
|
||||
<div class="related" role="navigation" aria-label="related navigation">
|
||||
<h3>导航</h3>
|
||||
<ul>
|
||||
<li class="right" style="margin-right: 10px">
|
||||
<a href="../genindex.html" title="总目录"
|
||||
>索引</a></li>
|
||||
<li class="right" >
|
||||
<a href="../py-modindex.html" title="Python 模块索引"
|
||||
>模块</a> |</li>
|
||||
<li class="right" >
|
||||
<a href="windows.html" title="Python在Windows上的常见问题"
|
||||
>下一页</a> |</li>
|
||||
<li class="right" >
|
||||
<a href="library.html" title="代码库和插件 FAQ"
|
||||
>上一页</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.8.20 Documentation</a> »
|
||||
</li>
|
||||
|
||||
<li class="nav-item nav-item-1"><a href="index.html" >Python 常见问题</a> »</li>
|
||||
<li class="right">
|
||||
|
||||
|
||||
<div class="inline-search" role="search">
|
||||
<form class="inline-search" action="../search.html" method="get">
|
||||
<input placeholder="快速搜索" aria-label="快速搜索" type="text" name="q" />
|
||||
<input type="submit" value="转向" />
|
||||
<input type="hidden" name="check_keywords" value="yes" />
|
||||
<input type="hidden" name="area" value="default" />
|
||||
</form>
|
||||
</div>
|
||||
|
|
||||
</li>
|
||||
|
||||
</ul>
|
||||
</div>
|
||||
<div class="footer">
|
||||
© <a href="../copyright.html">版权所有</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 />
|
||||
|
||||
<br />
|
||||
|
||||
The Python Software Foundation is a non-profit corporation.
|
||||
<a href="https://www.python.org/psf/donations/">Please donate.</a>
|
||||
<br />
|
||||
<br />
|
||||
|
||||
最后更新于 12月 09, 2024.
|
||||
<a href="https://docs.python.org/3/bugs.html">Found a bug</a>?
|
||||
<br />
|
||||
|
||||
Created using <a href="https://www.sphinx-doc.org/">Sphinx</a> 2.4.4.
|
||||
</div>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
478
web/python-docs/faq/general.html
Normal file
478
web/python-docs/faq/general.html
Normal file
@@ -0,0 +1,478 @@
|
||||
|
||||
<!DOCTYPE html>
|
||||
|
||||
<html xmlns="http://www.w3.org/1999/xhtml" lang="zh_CN">
|
||||
<head>
|
||||
<meta charset="utf-8" /><meta name="generator" content="Docutils 0.17.1: http://docutils.sourceforge.net/" />
|
||||
|
||||
<title>Python常见问题 — Python 3.8.20 文档</title><meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
|
||||
<link rel="stylesheet" href="../_static/pydoctheme.css" type="text/css" />
|
||||
<link rel="stylesheet" href="../_static/pygments.css" type="text/css" />
|
||||
|
||||
<script id="documentation_options" data-url_root="../" src="../_static/documentation_options.js"></script>
|
||||
<script src="../_static/jquery.js"></script>
|
||||
<script src="../_static/underscore.js"></script>
|
||||
<script src="../_static/doctools.js"></script>
|
||||
<script src="../_static/language_data.js"></script>
|
||||
<script src="../_static/translations.js"></script>
|
||||
|
||||
<script src="../_static/sidebar.js"></script>
|
||||
|
||||
<link rel="search" type="application/opensearchdescription+xml"
|
||||
title="在 Python 3.8.20 文档 中搜索"
|
||||
href="../_static/opensearch.xml"/>
|
||||
<link rel="author" title="关于这些文档" href="../about.html" />
|
||||
<link rel="index" title="索引" href="../genindex.html" />
|
||||
<link rel="search" title="搜索" href="../search.html" />
|
||||
<link rel="copyright" title="版权所有" href="../copyright.html" />
|
||||
<link rel="next" title="编程常见问题" href="programming.html" />
|
||||
<link rel="prev" title="Python 常见问题" href="index.html" />
|
||||
<link rel="canonical" href="https://docs.python.org/3/faq/general.html" />
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<style>
|
||||
@media only screen {
|
||||
table.full-width-table {
|
||||
width: 100%;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
<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>
|
||||
|
||||
</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" />
|
||||
<label for="menuToggler" class="toggler__label">
|
||||
<span></span>
|
||||
</label>
|
||||
<nav class="nav-content" role="navigation">
|
||||
<a href="https://www.python.org/" class="nav-logo">
|
||||
<img src="../_static/py.svg" alt="Logo"/>
|
||||
</a>
|
||||
<div class="version_switcher_placeholder"></div>
|
||||
<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"
|
||||
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" fill="#444"></path>
|
||||
</svg>
|
||||
<input type="text" name="q" aria-label="快速搜索"/>
|
||||
<input type="submit" value="转向"/>
|
||||
</form>
|
||||
</nav>
|
||||
<div class="menu-wrapper">
|
||||
<nav class="menu" role="navigation" aria-label="main navigation">
|
||||
<div class="language_switcher_placeholder"></div>
|
||||
<h3><a href="../contents.html">目录</a></h3>
|
||||
<ul>
|
||||
<li><a class="reference internal" href="#">Python常见问题</a><ul>
|
||||
<li><a class="reference internal" href="#general-information">一般信息</a></li>
|
||||
<li><a class="reference internal" href="#python-in-the-real-world">现实世界中的 Python</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<h4>上一个主题</h4>
|
||||
<p class="topless"><a href="index.html"
|
||||
title="上一章">Python 常见问题</a></p>
|
||||
<h4>下一个主题</h4>
|
||||
<p class="topless"><a href="programming.html"
|
||||
title="下一章">编程常见问题</a></p>
|
||||
<div role="note" aria-label="source link">
|
||||
<h3>本页</h3>
|
||||
<ul class="this-page-menu">
|
||||
<li><a href="../bugs.html">报告 Bug</a></li>
|
||||
<li>
|
||||
<a href="https://github.com/python/cpython/blob/3.8/Doc/faq/general.rst"
|
||||
rel="nofollow">显示源代码
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</nav>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="outdated-warning" style="padding: .5em; text-align: center; background-color: #FFBABA; color: #6A0E0E;">
|
||||
这个文档所针对的是一个已不再受支持的 Python 旧版本。
|
||||
你应当升级版本,并阅读
|
||||
<a href="/3/faq/general.html"> Python 当前稳定版本的文档</a>.
|
||||
</div>
|
||||
|
||||
<div class="related" role="navigation" aria-label="related navigation">
|
||||
<h3>导航</h3>
|
||||
<ul>
|
||||
<li class="right" style="margin-right: 10px">
|
||||
<a href="../genindex.html" title="总目录"
|
||||
accesskey="I">索引</a></li>
|
||||
<li class="right" >
|
||||
<a href="../py-modindex.html" title="Python 模块索引"
|
||||
>模块</a> |</li>
|
||||
<li class="right" >
|
||||
<a href="programming.html" title="编程常见问题"
|
||||
accesskey="N">下一页</a> |</li>
|
||||
<li class="right" >
|
||||
<a href="index.html" title="Python 常见问题"
|
||||
accesskey="P">上一页</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.8.20 Documentation</a> »
|
||||
</li>
|
||||
|
||||
<li class="nav-item nav-item-1"><a href="index.html" accesskey="U">Python 常见问题</a> »</li>
|
||||
<li class="right">
|
||||
|
||||
|
||||
<div class="inline-search" role="search">
|
||||
<form class="inline-search" action="../search.html" method="get">
|
||||
<input placeholder="快速搜索" aria-label="快速搜索" type="text" name="q" />
|
||||
<input type="submit" value="转向" />
|
||||
<input type="hidden" name="check_keywords" value="yes" />
|
||||
<input type="hidden" name="area" value="default" />
|
||||
</form>
|
||||
</div>
|
||||
|
|
||||
</li>
|
||||
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<div class="document">
|
||||
<div class="documentwrapper">
|
||||
<div class="bodywrapper">
|
||||
<div class="body" role="main">
|
||||
|
||||
<section id="general-python-faq">
|
||||
<h1><a class="toc-backref" href="#id3">Python常见问题</a><a class="headerlink" href="#general-python-faq" title="永久链接至标题">¶</a></h1>
|
||||
<div class="contents topic" id="id1">
|
||||
<p class="topic-title">目录</p>
|
||||
<ul class="simple">
|
||||
<li><p><a class="reference internal" href="#general-python-faq" id="id3">Python常见问题</a></p>
|
||||
<ul>
|
||||
<li><p><a class="reference internal" href="#general-information" id="id4">一般信息</a></p>
|
||||
<ul>
|
||||
<li><p><a class="reference internal" href="#what-is-python" id="id5">什么是 Python?</a></p></li>
|
||||
<li><p><a class="reference internal" href="#what-is-the-python-software-foundation" id="id6">什么是 Python 软件基金会?</a></p></li>
|
||||
<li><p><a class="reference internal" href="#are-there-copyright-restrictions-on-the-use-of-python" id="id7">使用 Python 是否存在版权限制?</a></p></li>
|
||||
<li><p><a class="reference internal" href="#why-was-python-created-in-the-first-place" id="id8">创造 Python 的最初理由是什么?</a></p></li>
|
||||
<li><p><a class="reference internal" href="#what-is-python-good-for" id="id9">Python 适合做什么?</a></p></li>
|
||||
<li><p><a class="reference internal" href="#how-does-the-python-version-numbering-scheme-work" id="id10">Python 版本的编号形式是怎样的?</a></p></li>
|
||||
<li><p><a class="reference internal" href="#how-do-i-obtain-a-copy-of-the-python-source" id="id11">我应如何获取一份 Python 源代码的副本?</a></p></li>
|
||||
<li><p><a class="reference internal" href="#how-do-i-get-documentation-on-python" id="id12">我应如何获取 Python 的文档?</a></p></li>
|
||||
<li><p><a class="reference internal" href="#i-ve-never-programmed-before-is-there-a-python-tutorial" id="id13">我之前从未接触过编程。 哪里有 Python 的教程?</a></p></li>
|
||||
<li><p><a class="reference internal" href="#is-there-a-newsgroup-or-mailing-list-devoted-to-python" id="id14">是否有专门针对 Python 的新闻组或邮件列表?</a></p></li>
|
||||
<li><p><a class="reference internal" href="#how-do-i-get-a-beta-test-version-of-python" id="id15">我应如何获取 Python 的公开测试版本?</a></p></li>
|
||||
<li><p><a class="reference internal" href="#how-do-i-submit-bug-reports-and-patches-for-python" id="id16">我应如何为 Python 提交错误报告和补丁?</a></p></li>
|
||||
<li><p><a class="reference internal" href="#are-there-any-published-articles-about-python-that-i-can-reference" id="id17">是否有任何公开发表的 Python 相关文章可以供我参考引用?</a></p></li>
|
||||
<li><p><a class="reference internal" href="#are-there-any-books-on-python" id="id18">是否有任何 Python 相关的书籍?</a></p></li>
|
||||
<li><p><a class="reference internal" href="#where-in-the-world-is-www-python-org-located" id="id19">www.python.org 具体位于世界上的哪个地点?</a></p></li>
|
||||
<li><p><a class="reference internal" href="#why-is-it-called-python" id="id20">为何命名为 Python?</a></p></li>
|
||||
<li><p><a class="reference internal" href="#do-i-have-to-like-monty-python-s-flying-circus" id="id21">我必须喜欢 "Monty Python 的飞行马戏团" 吗?</a></p></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li><p><a class="reference internal" href="#python-in-the-real-world" id="id22">现实世界中的 Python</a></p>
|
||||
<ul>
|
||||
<li><p><a class="reference internal" href="#how-stable-is-python" id="id23">Python 有多稳定?</a></p></li>
|
||||
<li><p><a class="reference internal" href="#how-many-people-are-using-python" id="id24">有多少人在使用 Python?</a></p></li>
|
||||
<li><p><a class="reference internal" href="#have-any-significant-projects-been-done-in-python" id="id25">有哪些重要的项目是用 Python 开发的?</a></p></li>
|
||||
<li><p><a class="reference internal" href="#what-new-developments-are-expected-for-python-in-the-future" id="id26">在未来可以期待 Python 将有什么新进展?</a></p></li>
|
||||
<li><p><a class="reference internal" href="#is-it-reasonable-to-propose-incompatible-changes-to-python" id="id27">提议对 Python 加入不兼容的更改是否合理?</a></p></li>
|
||||
<li><p><a class="reference internal" href="#is-python-a-good-language-for-beginning-programmers" id="id28">Python 是一种对编程初学者友好的语言吗?</a></p></li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
<section id="general-information">
|
||||
<h2><a class="toc-backref" href="#id4">一般信息</a><a class="headerlink" href="#general-information" title="永久链接至标题">¶</a></h2>
|
||||
<section id="what-is-python">
|
||||
<h3><a class="toc-backref" href="#id5">什么是 Python?</a><a class="headerlink" href="#what-is-python" title="永久链接至标题">¶</a></h3>
|
||||
<p>Python 是一种解释型、交互式、面向对象的编程语言。 它包含了模块、异常、动态类型、高层级动态数据类型以及类等特性。 在面向对象编程以外它还支持多种编程范式,例如过程式和函数式编程等。 Python 结合了超强的功能和极清晰的语法。 它带有许多系统调用和库以及多种窗口系统的接口,并且能用 C 或 C++ 来进行扩展。 它还可用作需要可编程接口的应用程序的扩展语言。 最后,Python 非常易于移植:它可以在包括 Linux 和 macOS 在内的许多 Unix 变种以及 Windows 上运行。</p>
|
||||
<p>要了解更多详情,请先查看 <a class="reference internal" href="../tutorial/index.html#tutorial-index"><span class="std std-ref">Python 教程</span></a>。 <a class="reference external" href="https://wiki.python.org/moin/BeginnersGuide">Python 新手指南</a> 提供了学习 Python 的其他入门教程及资源的链接。</p>
|
||||
</section>
|
||||
<section id="what-is-the-python-software-foundation">
|
||||
<h3><a class="toc-backref" href="#id6">什么是 Python 软件基金会?</a><a class="headerlink" href="#what-is-the-python-software-foundation" title="永久链接至标题">¶</a></h3>
|
||||
<p>Python 软件基金会(Python Software Foundation,简称 PSF)是一个独立的非盈利组织,它拥有 Python 2.1 及以上各版本的版权。 PSF 的使命是推进与 Python 编程语言相关的开源技术,并推广 Python 的使用。 PSF 的主页是 <a class="reference external" href="https://www.python.org/psf/">https://www.python.org/psf/</a>。</p>
|
||||
<p>向 PSF 提供捐助在美国是免税的。 如果你在使用 Python 并且感觉它对你很有帮助,可以通过 <a class="reference external" href="https://www.python.org/psf/donations/">PSF 捐助页</a> 进行捐助。</p>
|
||||
</section>
|
||||
<section id="are-there-copyright-restrictions-on-the-use-of-python">
|
||||
<h3><a class="toc-backref" href="#id7">使用 Python 是否存在版权限制?</a><a class="headerlink" href="#are-there-copyright-restrictions-on-the-use-of-python" title="永久链接至标题">¶</a></h3>
|
||||
<p>你可以任意使用源码,只要你保留版权信息并在你基于 Python 的产品文档中显示该版权信息。 如果你遵守此版权规则,就可以将 Python 用于商业领域,以源码或二进制码的形式(不论是否经过修改)销售 Python 的副本,或是以某种形式包含了 Python 的产品。 当然,我们仍然希望获知所有对 Python 的商业使用。</p>
|
||||
<p>请参阅 <a class="reference external" href="https://www.python.org/psf/license/">PSF 许可页</a> 以查看进一步的说明以及许可的完整文本内容的链接。</p>
|
||||
<p>Python 的徽标是注册商标,在某些情况下需要获得允许方可使用。 请参阅 <a class="reference external" href="https://www.python.org/psf/trademarks/">商标使用政策</a> 了解详情。</p>
|
||||
</section>
|
||||
<section id="why-was-python-created-in-the-first-place">
|
||||
<h3><a class="toc-backref" href="#id8">创造 Python 的最初理由是什么?</a><a class="headerlink" href="#why-was-python-created-in-the-first-place" title="永久链接至标题">¶</a></h3>
|
||||
<p>以下是有关最初缘起的一份 <em>非常</em> 简短的摘要,由 Guido van Rossum 本人撰写:</p>
|
||||
<blockquote>
|
||||
<div><p>我在 CWI 的 ABC 部门时在实现解释型语言方面积累了丰富经验,通过与这个部门成员的协同工作,我学到了大量有关语言设计的知识。 这是许多 Python 特性的最初来源,包括使用缩进来组织语句以及包含非常高层级的数据结构(虽然在 Python 中具体的实现细节完全不同)。</p>
|
||||
<p>我对 ABC 语言有过许多抱怨,但同时也很喜欢它的许多特性。 没有可能通过扩展 ABC 语言(或它的实现)来弥补我的不满 —— 实际上缺乏可扩展性就是它最大的问题之一。 我也有一些使用 Modula-2+ 的经验,并曾与 Modula-3 的设计者进行交流,还阅读了 Modula-3 的报告。 Modula-3 是 Python 中异常机制所用语法和语义,以及其他一些语言特性的最初来源。</p>
|
||||
<p>我还曾在 CWI 的 Amoeba 分布式操作系统部门工作。 当时我们需要有一种比编写 C 程序或 Bash 脚本更好的方式来进行系统管理,因为 Amoeba 有它自己的系统调用接口,并且无法方便地通过 Bash 来访问。 我在 Amoeba 中处理错误的经验令我深刻地意识到异常处理在编程语言特性当中的重要地位。</p>
|
||||
<p>我发现,某种具有 ABC 式的语法而又能访问 Amoeba 系统调用的脚本语言将可满足需求。 我意识到编写一种 Amoeba 专属的语言是愚蠢的,所以我决定编写一种具有全面可扩展性的语言。</p>
|
||||
<p>在 1989 年的圣诞假期中,我手头的时间非常充裕,因此我决定开始尝试一下。 在接下来的一年里,虽然我仍然主要用我的业余时间来做这件事,但 Python 在 Amoeba 项目中的使用获得了很大的成功,来自同事的反馈让我得以增加了许多早期的改进。</p>
|
||||
<p>到 1991 年 2 月,经过一年多的开发,我决定将其发布到 USENET。 之后的事情就都可以在 <code class="docutils literal notranslate"><span class="pre">Misc/HISTORY</span></code> 文件里面看了。</p>
|
||||
</div></blockquote>
|
||||
</section>
|
||||
<section id="what-is-python-good-for">
|
||||
<h3><a class="toc-backref" href="#id9">Python 适合做什么?</a><a class="headerlink" href="#what-is-python-good-for" title="永久链接至标题">¶</a></h3>
|
||||
<p>Python 是一种高层级的多用途编程语言,可用于解决许多不同门类的问题。</p>
|
||||
<p>该语言附带一个庞大的标准库,涵盖了字符串处理(正则表达式,Unicode,比较文件间的差异等),因特网协议(HTTP,FTP,SMTP,XML-RPC,POP,IMAP,CGI 编程等),软件工程(单元测试,日志记录,性能分析,Python 代码解析等),以及操作系统接口(系统调用,文件系统,TCP/IP 套接字等)。 请查看 <a class="reference internal" href="../library/index.html#library-index"><span class="std std-ref">Python 标准库</span></a> 的目录以了解所有可用的内容。 此外还可以获取到各种各样的第三方扩展。 请访问 <a class="reference external" href="https://pypi.org">Python 包索引</a> 来查找你感兴趣的软件包。</p>
|
||||
</section>
|
||||
<section id="how-does-the-python-version-numbering-scheme-work">
|
||||
<h3><a class="toc-backref" href="#id10">Python 版本的编号形式是怎样的?</a><a class="headerlink" href="#how-does-the-python-version-numbering-scheme-work" title="永久链接至标题">¶</a></h3>
|
||||
<p>Python 版本的编号形式是 A.B.C 或 A.B。 A 称为大版本号 —— 它仅在对语言特性进行非常重大改变时才会递增。 B 称为小版本号,它会在语言特性发生较小改变时递增。 C 称为微版本号 —— 它会在每次发布问题修正时递增。 请参阅 <span class="target" id="index-6"></span><a class="pep reference external" href="https://www.python.org/dev/peps/pep-0006"><strong>PEP 6</strong></a> 了解有关问题修正发布版的详情。</p>
|
||||
<p>发布版本并非都是问题修正版本。 在新的主要发布版本开发过程中,还会发布一系列的开发版,它们以 alpha (a), beta (b) 或 release candidate (rc) 来标示。 其中 alpha 版是早期发布的测试版,它的接口并未最终确定;在两个 alpha 发布版本间出现接口的改变并不意外。 而 beta 版更为稳定,它会保留现有的接口,但也可能增加新的模块,release candidate 版则会保持冻结状态不会再进行改变,除非有重大问题需要修正。</p>
|
||||
<p>以上 alpha, beta 和 release candidate 版本会附加一个后缀。 用于 alpha 版本的后缀是带有一个小数字 N 的 “aN”,beta 版本的后缀是带有一个小数字 N 的“bN”,release candidate 版本的后缀是带有一个小数字 N 的“cN”。 换句话说,所有标记为 2.0aN 的版本都早于标记为 2.0bN 的版本,后者又都早于标记为 2.0cN 的版本,而 <em>这些版本</em> 全都早于 2.0。</p>
|
||||
<p>你还可能看到带有“+”后缀的版本号,例如“2.2+”。 这表示未发布版本,直接基于 CPython 开发代码仓库构建。 在实际操作中,当一个小版本最终发布后,未发布版本号会递增到下一个小版本号,成为“a0”版本,例如“2.4a0”。</p>
|
||||
<p>另请参阅 <a class="reference internal" href="../library/sys.html#sys.version" title="sys.version"><code class="xref py py-data docutils literal notranslate"><span class="pre">sys.version</span></code></a>, <a class="reference internal" href="../library/sys.html#sys.hexversion" title="sys.hexversion"><code class="xref py py-data docutils literal notranslate"><span class="pre">sys.hexversion</span></code></a> 以及 <a class="reference internal" href="../library/sys.html#sys.version_info" title="sys.version_info"><code class="xref py py-data docutils literal notranslate"><span class="pre">sys.version_info</span></code></a> 的文档。</p>
|
||||
</section>
|
||||
<section id="how-do-i-obtain-a-copy-of-the-python-source">
|
||||
<h3><a class="toc-backref" href="#id11">我应如何获取一份 Python 源代码的副本?</a><a class="headerlink" href="#how-do-i-obtain-a-copy-of-the-python-source" title="永久链接至标题">¶</a></h3>
|
||||
<p>最新的 Python 发布版源代码总能从 python.org 获取,下载页链接为 <a class="reference external" href="https://www.python.org/downloads/">https://www.python.org/downloads/</a>。 最新的开发版源代码可以在 <a class="reference external" href="https://github.com/python/cpython/">https://github.com/python/cpython/</a> 获取。</p>
|
||||
<p>发布版源代码是一个以 gzip 压缩的 tar 文件,其中包含完整的 C 源代码、Sphinx 格式的文档、Python 库模块、示例程序以及一些有用的自由分发软件。 该源代码将可在大多数 UNIX 类平台上直接编译并运行。</p>
|
||||
<p>请参阅 <a class="reference external" href="https://devguide.python.org/setup/">Python 开发者指南的初步上手部分</a> 了解有关获取源代码并进行编译的更多信息。</p>
|
||||
</section>
|
||||
<section id="how-do-i-get-documentation-on-python">
|
||||
<h3><a class="toc-backref" href="#id12">我应如何获取 Python 的文档?</a><a class="headerlink" href="#how-do-i-get-documentation-on-python" title="永久链接至标题">¶</a></h3>
|
||||
<p>当前的 Python 稳定版本的标准文档可在 <a class="reference external" href="https://docs.python.org/3/">https://docs.python.org/3/</a> 查看。 也可在 <a class="reference external" href="https://docs.python.org/3/download.html">https://docs.python.org/3/download.html</a> 获取PDF、纯文本以及可下载的 HTML 版本。</p>
|
||||
<p>文档以 reStructuredText 格式撰写,并使用 <a class="reference external" href="http://sphinx-doc.org/">Sphinx 文档工具</a> 生成。 文档的 reStructuredText 源文件是 Python 源代码发布版的一部分。</p>
|
||||
</section>
|
||||
<section id="i-ve-never-programmed-before-is-there-a-python-tutorial">
|
||||
<h3><a class="toc-backref" href="#id13">我之前从未接触过编程。 哪里有 Python 的教程?</a><a class="headerlink" href="#i-ve-never-programmed-before-is-there-a-python-tutorial" title="永久链接至标题">¶</a></h3>
|
||||
<p>有许多可选择的教程和书籍。 标准文档中也包含有 <a class="reference internal" href="../tutorial/index.html#tutorial-index"><span class="std std-ref">Python 教程</span></a>。</p>
|
||||
<p>请参阅 <a class="reference external" href="https://wiki.python.org/moin/BeginnersGuide">新手指南</a> 以获取针对 Python 编程初学者的信息,包括教程的清单。</p>
|
||||
</section>
|
||||
<section id="is-there-a-newsgroup-or-mailing-list-devoted-to-python">
|
||||
<h3><a class="toc-backref" href="#id14">是否有专门针对 Python 的新闻组或邮件列表?</a><a class="headerlink" href="#is-there-a-newsgroup-or-mailing-list-devoted-to-python" title="永久链接至标题">¶</a></h3>
|
||||
<p>有一个新闻组 <em class="newsgroup">comp.lang.python</em> 和一个邮件列表 <a class="reference external" href="https://mail.python.org/mailman/listinfo/python-list">python-list</a>。 新闻组和邮件列表是彼此互通的 —— 如果你可以阅读新闻就不必再订阅邮件列表。 <em class="newsgroup">comp.lang.python</em> 的流量很大,每天会收到数以百计的发帖,Usenet 使用者通常更擅长处理这样大的流量。</p>
|
||||
<p>有关新软件发布和活动的公告可以在 comp.lang.python.announce 中找到,这是个严格管理的低流量列表,每天会收到五个左右的发帖。 可以在 <a class="reference external" href="https://mail.python.org/mailman/listinfo/python-announce-list">Python 公告邮件列表</a> 页面进行订阅。</p>
|
||||
<p>有关其他邮件列表和新闻组的更多信息可以在 <a class="reference external" href="https://www.python.org/community/lists/">https://www.python.org/community/lists/</a> 找到。</p>
|
||||
</section>
|
||||
<section id="how-do-i-get-a-beta-test-version-of-python">
|
||||
<h3><a class="toc-backref" href="#id15">我应如何获取 Python 的公开测试版本?</a><a class="headerlink" href="#how-do-i-get-a-beta-test-version-of-python" title="永久链接至标题">¶</a></h3>
|
||||
<p>可以从 <a class="reference external" href="https://www.python.org/downloads/">https://www.python.org/downloads/</a> 下载 alpha 和 beta 发布版。 所有发布版都会在 comp.lang.python 和 comp.lang.python.announce 新闻组以及 Python 主页 <a class="reference external" href="https://www.python.org/">https://www.python.org/</a> 上进行公告;并会推送到 RSS 新闻源。</p>
|
||||
<p>你还可以通过 Git 访问 Python 的开发版。 请参阅 <a class="reference external" href="https://devguide.python.org/">Python 开发者指南</a> 了解详情。</p>
|
||||
</section>
|
||||
<section id="how-do-i-submit-bug-reports-and-patches-for-python">
|
||||
<h3><a class="toc-backref" href="#id16">我应如何为 Python 提交错误报告和补丁?</a><a class="headerlink" href="#how-do-i-submit-bug-reports-and-patches-for-python" title="永久链接至标题">¶</a></h3>
|
||||
<p>要报告错误或提交补丁,请使用安装于 <a class="reference external" href="https://bugs.python.org/">https://bugs.python.org/</a> 上的 Roundup。</p>
|
||||
<p>你必须拥有一个 Roundup 账号才能报告错误;这样我们就可以在有后续问题时与你联系。 这也使得 Roundup 能在我们处理所报告的错误时向你发送更新消息。 如果你之前使用过 SourceForge 向 Python 报告错误,你可以通过 Roundup 的 <a class="reference external" href="https://bugs.python.org/user?@template=forgotten">密码重置操作</a> 来获取你的 Roundup 密码。</p>
|
||||
<p>有关 Python 开发流程的更多信息,请参阅 <a class="reference external" href="https://devguide.python.org/">Python 开发者指南</a>。</p>
|
||||
</section>
|
||||
<section id="are-there-any-published-articles-about-python-that-i-can-reference">
|
||||
<h3><a class="toc-backref" href="#id17">是否有任何公开发表的 Python 相关文章可以供我参考引用?</a><a class="headerlink" href="#are-there-any-published-articles-about-python-that-i-can-reference" title="永久链接至标题">¶</a></h3>
|
||||
<p>可能作为参考文献的最好方式还是引用你喜欢的 Python 相关书籍。</p>
|
||||
<p>第一篇有关 Python 的文章写于 1991 年,现在其内容已经相当过时了。</p>
|
||||
<blockquote>
|
||||
<div><p>Guido van Rossum 与 Jelke de Boer, "使用 Python 编程语言交互式地测试远程服务器", CWI 季刊, 第 4 卷, 第 4 期 (1991 年 12 月), 阿姆斯特丹, 第 283--303 页。</p>
|
||||
</div></blockquote>
|
||||
</section>
|
||||
<section id="are-there-any-books-on-python">
|
||||
<h3><a class="toc-backref" href="#id18">是否有任何 Python 相关的书籍?</a><a class="headerlink" href="#are-there-any-books-on-python" title="永久链接至标题">¶</a></h3>
|
||||
<p>是的,相关的书籍很多,还有更多即将发行。 请访问 python.org 的 wiki 页面 <a class="reference external" href="https://wiki.python.org/moin/PythonBooks">https://wiki.python.org/moin/PythonBooks</a> 获取一份清单。</p>
|
||||
<p>你也可以到各大在线书店搜索 "Python" 并过滤掉对 Monty Python 的引用;或者也可以搜索 "Python" 加 "language"。</p>
|
||||
</section>
|
||||
<section id="where-in-the-world-is-www-python-org-located">
|
||||
<h3><a class="toc-backref" href="#id19">www.python.org 具体位于世界上的哪个地点?</a><a class="headerlink" href="#where-in-the-world-is-www-python-org-located" title="永久链接至标题">¶</a></h3>
|
||||
<p>Python 项目的基础架构分布于世界各地并由 Python 基础架构团队负责管理。 详情请访问 <a class="reference external" href="http://infra.psf.io">这里</a>。</p>
|
||||
</section>
|
||||
<section id="why-is-it-called-python">
|
||||
<h3><a class="toc-backref" href="#id20">为何命名为 Python?</a><a class="headerlink" href="#why-is-it-called-python" title="永久链接至标题">¶</a></h3>
|
||||
<p>在着手编写 Python 实现的时候,Guido van Rossum 同时还阅读了刚出版的 <a class="reference external" href="https://en.wikipedia.org/wiki/Monty_Python">"Monty Python 的飞行马戏团"</a> 剧本,这是一部自 1970 年代开始播出的 BBC 系列喜剧。 Van Rossum 觉得他需要选择一个简短、独特而又略显神秘的名字,于是他决定将这个新语言命名为 Python。</p>
|
||||
</section>
|
||||
<section id="do-i-have-to-like-monty-python-s-flying-circus">
|
||||
<h3><a class="toc-backref" href="#id21">我必须喜欢 "Monty Python 的飞行马戏团" 吗?</a><a class="headerlink" href="#do-i-have-to-like-monty-python-s-flying-circus" title="永久链接至标题">¶</a></h3>
|
||||
<p>不必,但这对学习会有帮助。 :)</p>
|
||||
</section>
|
||||
</section>
|
||||
<section id="python-in-the-real-world">
|
||||
<h2><a class="toc-backref" href="#id22">现实世界中的 Python</a><a class="headerlink" href="#python-in-the-real-world" title="永久链接至标题">¶</a></h2>
|
||||
<section id="how-stable-is-python">
|
||||
<h3><a class="toc-backref" href="#id23">Python 有多稳定?</a><a class="headerlink" href="#how-stable-is-python" title="永久链接至标题">¶</a></h3>
|
||||
<p>非常稳定。 自 1991 年起大约每隔 6 到 18 个月就会推出新的稳定发布版,这种状态看来还还持续。 从 3.9 版开始,Python 将会每隔 12 个月推出一个新的主要发布版 (<span class="target" id="index-7"></span><a class="pep reference external" href="https://www.python.org/dev/peps/pep-0602"><strong>PEP 602</strong></a>)。</p>
|
||||
<p>开发者也会推出旧版本的“问题修正”发布版,因此现有发布版的稳定性还会逐步提升。 问题修正发布版会以版本号第三部分的数字来标示(例如 3.5.3, 3.6.2),用于稳定性的管理;只有对已知问题的修正会包含在问题修正发布版中,同一系列的问题修正发布版中的接口确定将会始终保持一致。</p>
|
||||
<p>最新的稳定版本总是可以在 <a class="reference external" href="https://www.python.org/downloads/">Python 下载页面</a> 上找到。有两个生产环境可用的 Python 版本: 2.x 和 3.x。 推荐的版本是 3.x,大多数广泛使用的库都支持它。 虽然 2.x 仍然被广泛使用,但它 <a class="reference external" href="https://www.python.org/dev/peps/pep-0373/">在 2020 年 1 月 1 日之后将不再维护</a>。</p>
|
||||
</section>
|
||||
<section id="how-many-people-are-using-python">
|
||||
<h3><a class="toc-backref" href="#id24">有多少人在使用 Python?</a><a class="headerlink" href="#how-many-people-are-using-python" title="永久链接至标题">¶</a></h3>
|
||||
<p>使用者应该数以百万计,但很难获得一个精确的数字。</p>
|
||||
<p>Python 可以免费下载,因此并不存在销量数据,此外它也可以从许多不同网站获取,并且包含于许多 Linux 发行版之中,因此下载量统计同样无法完全说明问题。</p>
|
||||
<p>comp.lang.python 新闻组非常活跃,但不是所有 Python 用户都会在新闻组发帖,许多人甚至不会阅读新闻组。</p>
|
||||
</section>
|
||||
<section id="have-any-significant-projects-been-done-in-python">
|
||||
<h3><a class="toc-backref" href="#id25">有哪些重要的项目是用 Python 开发的?</a><a class="headerlink" href="#have-any-significant-projects-been-done-in-python" title="永久链接至标题">¶</a></h3>
|
||||
<p>请访问 <a class="reference external" href="https://www.python.org/about/success">https://www.python.org/about/success</a> 查看使用了 Python 的项目列表。 阅览 <a class="reference external" href="https://www.python.org/community/workshops/">历次 Python 会议</a> 的日程纪要可以看到许多不同公司和组织所做的贡献。</p>
|
||||
<p>高水准的 Python 项目包括 <a class="reference external" href="http://www.list.org">Mailman 邮件列表管理器</a> 和 <a class="reference external" href="http://www.zope.org">Zope 应用服务器</a>。 多个 Linux 发行版,其中最著名的有 <a class="reference external" href="https://www.redhat.com">Red Hat</a> 均已使用 Python 来编写部分或全部的安装程序和系统管理软件。 在内部使用 Python 的大公司包括了 Google, Yahoo 以及 Lucasfilm 等。</p>
|
||||
</section>
|
||||
<section id="what-new-developments-are-expected-for-python-in-the-future">
|
||||
<h3><a class="toc-backref" href="#id26">在未来可以期待 Python 将有什么新进展?</a><a class="headerlink" href="#what-new-developments-are-expected-for-python-in-the-future" title="永久链接至标题">¶</a></h3>
|
||||
<p>请访问 <a class="reference external" href="https://www.python.org/dev/peps/">https://www.python.org/dev/peps/</a> 查看 Python 增强提议(PEP)。 PEP 是为 Python 加入某种新特性的提议进行描述的设计文档,其中会提供简明的技术规格说明与基本原理。 可以查找标题为“Python X.Y Release Schedule”的 PEP,其中 X.Y 是某个尚未公开发布的版本。</p>
|
||||
<p>新版本的开发会在 <a class="reference external" href="https://mail.python.org/mailman/listinfo/python-dev/">python-dev 邮件列表</a> 中进行讨论。</p>
|
||||
</section>
|
||||
<section id="is-it-reasonable-to-propose-incompatible-changes-to-python">
|
||||
<h3><a class="toc-backref" href="#id27">提议对 Python 加入不兼容的更改是否合理?</a><a class="headerlink" href="#is-it-reasonable-to-propose-incompatible-changes-to-python" title="永久链接至标题">¶</a></h3>
|
||||
<p>通常来说是不合理的。 世界上已存在的 Python 代码数以亿计,因此,任何对该语言的更改即便仅会使得现有程序中极少的一部分失效也是难以令人接受的。 就算你可以提供一个转换程序,也仍然存在需要更新全部文档的问题;另外还有大量已出版的 Python 书籍,我们不希望让它们在一瞬间全部变成废纸。</p>
|
||||
<p>如果必须更改某个特性,则应该提供渐进式的升级路径。 <span class="target" id="index-8"></span><a class="pep reference external" href="https://www.python.org/dev/peps/pep-0005"><strong>PEP 5</strong></a> 描述了引入向后不兼容的更改所需遵循的流程,以尽可能减少对用户的干扰。</p>
|
||||
</section>
|
||||
<section id="is-python-a-good-language-for-beginning-programmers">
|
||||
<h3><a class="toc-backref" href="#id28">Python 是一种对编程初学者友好的语言吗?</a><a class="headerlink" href="#is-python-a-good-language-for-beginning-programmers" title="永久链接至标题">¶</a></h3>
|
||||
<p>是的。</p>
|
||||
<p>从过程式、静态类型的编程语言例如 Pascal, C 或者 C++ 以及 Java 的某一子集开始引导学生入门仍然是常见的做法。 但以 Python 作为第一种编程语言进行学习对学生可能更有利。Python 具有非常简单和一致的语法和庞大的标准库,而且最重要的是,在编程入门教学中使用 Python 可以让学生专注于更重要的编程技能,例如问题分解与数据类型设计。 使用 Python,可以快速向学生介绍基本概念例如循环与过程等。 他们甚至有可能在第一次课里就开始接触用户自定义对象。</p>
|
||||
<p>对于之前从未接触过编程的学生来说,使用静态类型语言会感觉不够自然。 这会给学生带来必须掌握的额外复杂性,并减慢教学的进度。 学生需要尝试像计算机一样思考,分解问题,设计一致的接口并封装数据。 虽然从长远来看,学习和使用一种静态类型语言是很重要的,但这并不是最适宜在学生的第一次编程课上就进行探讨的主题。</p>
|
||||
<p>还有许多其他方面的特点使得 Python 成为很好的入门语言。 像 Java 一样,Python 拥有一个庞大的标准库,因此可以在课程非常早期的阶段就给学生布置一些 <em>实用</em> 的编程项目。 编程作业不必仅限于标准四则运算和账目检查程序。 通过使用标准库,学生可以在学习编程基础知识的同时开发真正的应用,从而获得更大的满足感。 使用标准库还能使学生了解代码重用的概念。 而像 PyGame 这样的第三方模块同样有助于扩大学生的接触领域。</p>
|
||||
<p>Python 的解释器使学生能够在编程时测试语言特性。 他们可以在一个窗口中输入程序源代码的同时开启一个解释器运行窗口。 如果他们不记得列表有哪些方法,他们这以这样做:</p>
|
||||
<div class="highlight-python3 notranslate"><div class="highlight"><pre><span></span><span class="gp">>>> </span><span class="n">L</span> <span class="o">=</span> <span class="p">[]</span>
|
||||
<span class="gp">>>> </span><span class="nb">dir</span><span class="p">(</span><span class="n">L</span><span class="p">)</span>
|
||||
<span class="go">['__add__', '__class__', '__contains__', '__delattr__', '__delitem__',</span>
|
||||
<span class="go">'__dir__', '__doc__', '__eq__', '__format__', '__ge__',</span>
|
||||
<span class="go">'__getattribute__', '__getitem__', '__gt__', '__hash__', '__iadd__',</span>
|
||||
<span class="go">'__imul__', '__init__', '__iter__', '__le__', '__len__', '__lt__',</span>
|
||||
<span class="go">'__mul__', '__ne__', '__new__', '__reduce__', '__reduce_ex__',</span>
|
||||
<span class="go">'__repr__', '__reversed__', '__rmul__', '__setattr__', '__setitem__',</span>
|
||||
<span class="go">'__sizeof__', '__str__', '__subclasshook__', 'append', 'clear',</span>
|
||||
<span class="go">'copy', 'count', 'extend', 'index', 'insert', 'pop', 'remove',</span>
|
||||
<span class="go">'reverse', 'sort']</span>
|
||||
<span class="gp">>>> </span><span class="p">[</span><span class="n">d</span> <span class="k">for</span> <span class="n">d</span> <span class="ow">in</span> <span class="nb">dir</span><span class="p">(</span><span class="n">L</span><span class="p">)</span> <span class="k">if</span> <span class="s1">'__'</span> <span class="ow">not</span> <span class="ow">in</span> <span class="n">d</span><span class="p">]</span>
|
||||
<span class="go">['append', 'clear', 'copy', 'count', 'extend', 'index', 'insert', 'pop', 'remove', 'reverse', 'sort']</span>
|
||||
|
||||
<span class="gp">>>> </span><span class="n">help</span><span class="p">(</span><span class="n">L</span><span class="o">.</span><span class="n">append</span><span class="p">)</span>
|
||||
<span class="go">Help on built-in function append:</span>
|
||||
|
||||
<span class="go">append(...)</span>
|
||||
<span class="go"> L.append(object) -> None -- append object to end</span>
|
||||
|
||||
<span class="gp">>>> </span><span class="n">L</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="mi">1</span><span class="p">)</span>
|
||||
<span class="gp">>>> </span><span class="n">L</span>
|
||||
<span class="go">[1]</span>
|
||||
</pre></div>
|
||||
</div>
|
||||
<p>通过使用解释器,学生编写程序时参考文档总是能伴随在他们身边。</p>
|
||||
<p>Python 还拥有很好的 IDE。 IDLE 是一个跨平台的 Python IDE,它基于 Tkinter 库,使用 Python 语言编写。 PythonWin 是一个 Windows 专属的 IDE。 Emacs 用户将高兴地了解到 Emacs 具有非常好的 Python 模式。 所有这些编程环境都提供语法高亮,自动缩进以及在编写代码时使用交互式解释器等功能。 请访问 <a class="reference external" href="https://wiki.python.org/moin/PythonEditors">Python wiki</a> 查看 Python 编程环境的完整列表。</p>
|
||||
<p>如果你想要讨论 Python 在教育中的使用,你可能会有兴趣加入 <a class="reference external" href="https://www.python.org/community/sigs/current/edu-sig">edu-sig 邮件列表</a>。</p>
|
||||
</section>
|
||||
</section>
|
||||
</section>
|
||||
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="sphinxsidebar" role="navigation" aria-label="main navigation">
|
||||
<div class="sphinxsidebarwrapper">
|
||||
<h3><a href="../contents.html">目录</a></h3>
|
||||
<ul>
|
||||
<li><a class="reference internal" href="#">Python常见问题</a><ul>
|
||||
<li><a class="reference internal" href="#general-information">一般信息</a></li>
|
||||
<li><a class="reference internal" href="#python-in-the-real-world">现实世界中的 Python</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<h4>上一个主题</h4>
|
||||
<p class="topless"><a href="index.html"
|
||||
title="上一章">Python 常见问题</a></p>
|
||||
<h4>下一个主题</h4>
|
||||
<p class="topless"><a href="programming.html"
|
||||
title="下一章">编程常见问题</a></p>
|
||||
<div role="note" aria-label="source link">
|
||||
<h3>本页</h3>
|
||||
<ul class="this-page-menu">
|
||||
<li><a href="../bugs.html">报告 Bug</a></li>
|
||||
<li>
|
||||
<a href="https://github.com/python/cpython/blob/3.8/Doc/faq/general.rst"
|
||||
rel="nofollow">显示源代码
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="clearer"></div>
|
||||
</div>
|
||||
<div class="related" role="navigation" aria-label="related navigation">
|
||||
<h3>导航</h3>
|
||||
<ul>
|
||||
<li class="right" style="margin-right: 10px">
|
||||
<a href="../genindex.html" title="总目录"
|
||||
>索引</a></li>
|
||||
<li class="right" >
|
||||
<a href="../py-modindex.html" title="Python 模块索引"
|
||||
>模块</a> |</li>
|
||||
<li class="right" >
|
||||
<a href="programming.html" title="编程常见问题"
|
||||
>下一页</a> |</li>
|
||||
<li class="right" >
|
||||
<a href="index.html" title="Python 常见问题"
|
||||
>上一页</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.8.20 Documentation</a> »
|
||||
</li>
|
||||
|
||||
<li class="nav-item nav-item-1"><a href="index.html" >Python 常见问题</a> »</li>
|
||||
<li class="right">
|
||||
|
||||
|
||||
<div class="inline-search" role="search">
|
||||
<form class="inline-search" action="../search.html" method="get">
|
||||
<input placeholder="快速搜索" aria-label="快速搜索" type="text" name="q" />
|
||||
<input type="submit" value="转向" />
|
||||
<input type="hidden" name="check_keywords" value="yes" />
|
||||
<input type="hidden" name="area" value="default" />
|
||||
</form>
|
||||
</div>
|
||||
|
|
||||
</li>
|
||||
|
||||
</ul>
|
||||
</div>
|
||||
<div class="footer">
|
||||
© <a href="../copyright.html">版权所有</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 />
|
||||
|
||||
<br />
|
||||
|
||||
The Python Software Foundation is a non-profit corporation.
|
||||
<a href="https://www.python.org/psf/donations/">Please donate.</a>
|
||||
<br />
|
||||
<br />
|
||||
|
||||
最后更新于 12月 09, 2024.
|
||||
<a href="https://docs.python.org/3/bugs.html">Found a bug</a>?
|
||||
<br />
|
||||
|
||||
Created using <a href="https://www.sphinx-doc.org/">Sphinx</a> 2.4.4.
|
||||
</div>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
367
web/python-docs/faq/gui.html
Normal file
367
web/python-docs/faq/gui.html
Normal file
@@ -0,0 +1,367 @@
|
||||
|
||||
<!DOCTYPE html>
|
||||
|
||||
<html xmlns="http://www.w3.org/1999/xhtml" lang="zh_CN">
|
||||
<head>
|
||||
<meta charset="utf-8" /><meta name="generator" content="Docutils 0.17.1: http://docutils.sourceforge.net/" />
|
||||
|
||||
<title>图形用户界面(GUI)常见问题 — Python 3.8.20 文档</title><meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
|
||||
<link rel="stylesheet" href="../_static/pydoctheme.css" type="text/css" />
|
||||
<link rel="stylesheet" href="../_static/pygments.css" type="text/css" />
|
||||
|
||||
<script id="documentation_options" data-url_root="../" src="../_static/documentation_options.js"></script>
|
||||
<script src="../_static/jquery.js"></script>
|
||||
<script src="../_static/underscore.js"></script>
|
||||
<script src="../_static/doctools.js"></script>
|
||||
<script src="../_static/language_data.js"></script>
|
||||
<script src="../_static/translations.js"></script>
|
||||
|
||||
<script src="../_static/sidebar.js"></script>
|
||||
|
||||
<link rel="search" type="application/opensearchdescription+xml"
|
||||
title="在 Python 3.8.20 文档 中搜索"
|
||||
href="../_static/opensearch.xml"/>
|
||||
<link rel="author" title="关于这些文档" href="../about.html" />
|
||||
<link rel="index" title="索引" href="../genindex.html" />
|
||||
<link rel="search" title="搜索" href="../search.html" />
|
||||
<link rel="copyright" title="版权所有" href="../copyright.html" />
|
||||
<link rel="next" title="“为什么我的电脑上安装了 Python ?”" href="installed.html" />
|
||||
<link rel="prev" title="Python在Windows上的常见问题" href="windows.html" />
|
||||
<link rel="canonical" href="https://docs.python.org/3/faq/gui.html" />
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<style>
|
||||
@media only screen {
|
||||
table.full-width-table {
|
||||
width: 100%;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
<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>
|
||||
|
||||
</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" />
|
||||
<label for="menuToggler" class="toggler__label">
|
||||
<span></span>
|
||||
</label>
|
||||
<nav class="nav-content" role="navigation">
|
||||
<a href="https://www.python.org/" class="nav-logo">
|
||||
<img src="../_static/py.svg" alt="Logo"/>
|
||||
</a>
|
||||
<div class="version_switcher_placeholder"></div>
|
||||
<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"
|
||||
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" fill="#444"></path>
|
||||
</svg>
|
||||
<input type="text" name="q" aria-label="快速搜索"/>
|
||||
<input type="submit" value="转向"/>
|
||||
</form>
|
||||
</nav>
|
||||
<div class="menu-wrapper">
|
||||
<nav class="menu" role="navigation" aria-label="main navigation">
|
||||
<div class="language_switcher_placeholder"></div>
|
||||
<h3><a href="../contents.html">目录</a></h3>
|
||||
<ul>
|
||||
<li><a class="reference internal" href="#">图形用户界面(GUI)常见问题</a><ul>
|
||||
<li><a class="reference internal" href="#general-gui-questions">图形界面常见问题</a></li>
|
||||
<li><a class="reference internal" href="#what-platform-independent-gui-toolkits-exist-for-python">Python 是否有平台无关的图形界面工具包?</a></li>
|
||||
<li><a class="reference internal" href="#what-platform-specific-gui-toolkits-exist-for-python">有哪些Python的GUI工具是某个平台专用的?</a></li>
|
||||
<li><a class="reference internal" href="#tkinter-questions">有关Tkinter的问题</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<h4>上一个主题</h4>
|
||||
<p class="topless"><a href="windows.html"
|
||||
title="上一章">Python在Windows上的常见问题</a></p>
|
||||
<h4>下一个主题</h4>
|
||||
<p class="topless"><a href="installed.html"
|
||||
title="下一章">“为什么我的电脑上安装了 Python ?”</a></p>
|
||||
<div role="note" aria-label="source link">
|
||||
<h3>本页</h3>
|
||||
<ul class="this-page-menu">
|
||||
<li><a href="../bugs.html">报告 Bug</a></li>
|
||||
<li>
|
||||
<a href="https://github.com/python/cpython/blob/3.8/Doc/faq/gui.rst"
|
||||
rel="nofollow">显示源代码
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</nav>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="outdated-warning" style="padding: .5em; text-align: center; background-color: #FFBABA; color: #6A0E0E;">
|
||||
这个文档所针对的是一个已不再受支持的 Python 旧版本。
|
||||
你应当升级版本,并阅读
|
||||
<a href="/3/faq/gui.html"> Python 当前稳定版本的文档</a>.
|
||||
</div>
|
||||
|
||||
<div class="related" role="navigation" aria-label="related navigation">
|
||||
<h3>导航</h3>
|
||||
<ul>
|
||||
<li class="right" style="margin-right: 10px">
|
||||
<a href="../genindex.html" title="总目录"
|
||||
accesskey="I">索引</a></li>
|
||||
<li class="right" >
|
||||
<a href="../py-modindex.html" title="Python 模块索引"
|
||||
>模块</a> |</li>
|
||||
<li class="right" >
|
||||
<a href="installed.html" title="“为什么我的电脑上安装了 Python ?”"
|
||||
accesskey="N">下一页</a> |</li>
|
||||
<li class="right" >
|
||||
<a href="windows.html" title="Python在Windows上的常见问题"
|
||||
accesskey="P">上一页</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.8.20 Documentation</a> »
|
||||
</li>
|
||||
|
||||
<li class="nav-item nav-item-1"><a href="index.html" accesskey="U">Python 常见问题</a> »</li>
|
||||
<li class="right">
|
||||
|
||||
|
||||
<div class="inline-search" role="search">
|
||||
<form class="inline-search" action="../search.html" method="get">
|
||||
<input placeholder="快速搜索" aria-label="快速搜索" type="text" name="q" />
|
||||
<input type="submit" value="转向" />
|
||||
<input type="hidden" name="check_keywords" value="yes" />
|
||||
<input type="hidden" name="area" value="default" />
|
||||
</form>
|
||||
</div>
|
||||
|
|
||||
</li>
|
||||
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<div class="document">
|
||||
<div class="documentwrapper">
|
||||
<div class="bodywrapper">
|
||||
<div class="body" role="main">
|
||||
|
||||
<section id="graphic-user-interface-faq">
|
||||
<h1><a class="toc-backref" href="#id3">图形用户界面(GUI)常见问题</a><a class="headerlink" href="#graphic-user-interface-faq" title="永久链接至标题">¶</a></h1>
|
||||
<div class="contents topic" id="id1">
|
||||
<p class="topic-title">目录</p>
|
||||
<ul class="simple">
|
||||
<li><p><a class="reference internal" href="#graphic-user-interface-faq" id="id3">图形用户界面(GUI)常见问题</a></p>
|
||||
<ul>
|
||||
<li><p><a class="reference internal" href="#general-gui-questions" id="id4">图形界面常见问题</a></p></li>
|
||||
<li><p><a class="reference internal" href="#what-platform-independent-gui-toolkits-exist-for-python" id="id5">Python 是否有平台无关的图形界面工具包?</a></p>
|
||||
<ul>
|
||||
<li><p><a class="reference internal" href="#tkinter" id="id6">Tkinter</a></p></li>
|
||||
<li><p><a class="reference internal" href="#wxwidgets" id="id7">wxWidgets</a></p></li>
|
||||
<li><p><a class="reference internal" href="#qt" id="id8">Qt</a></p></li>
|
||||
<li><p><a class="reference internal" href="#gtk" id="id9">Gtk+</a></p></li>
|
||||
<li><p><a class="reference internal" href="#kivy" id="id10">Kivy</a></p></li>
|
||||
<li><p><a class="reference internal" href="#fltk" id="id11">FLTK</a></p></li>
|
||||
<li><p><a class="reference internal" href="#opengl" id="id12">OpenGL</a></p></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li><p><a class="reference internal" href="#what-platform-specific-gui-toolkits-exist-for-python" id="id13">有哪些Python的GUI工具是某个平台专用的?</a></p></li>
|
||||
<li><p><a class="reference internal" href="#tkinter-questions" id="id14">有关Tkinter的问题</a></p>
|
||||
<ul>
|
||||
<li><p><a class="reference internal" href="#how-do-i-freeze-tkinter-applications" id="id15">我怎样“冻结”Tkinter程序?</a></p></li>
|
||||
<li><p><a class="reference internal" href="#can-i-have-tk-events-handled-while-waiting-for-i-o" id="id16">在等待 I/O 操作时能够处理 Tk 事件吗?</a></p></li>
|
||||
<li><p><a class="reference internal" href="#i-can-t-get-key-bindings-to-work-in-tkinter-why" id="id17">在Tkinter中键绑定不工作:为什么?</a></p></li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
<section id="general-gui-questions">
|
||||
<h2><a class="toc-backref" href="#id4">图形界面常见问题</a><a class="headerlink" href="#general-gui-questions" title="永久链接至标题">¶</a></h2>
|
||||
</section>
|
||||
<section id="what-platform-independent-gui-toolkits-exist-for-python">
|
||||
<h2><a class="toc-backref" href="#id5">Python 是否有平台无关的图形界面工具包?</a><a class="headerlink" href="#what-platform-independent-gui-toolkits-exist-for-python" title="永久链接至标题">¶</a></h2>
|
||||
<p>针对不同的(操作系统或)平台,有多种工具包可供选择。虽然有些工具包还没有移植到 Python 3 上,但至少目前 <a class="reference internal" href="#tkinter">Tkinter</a> 以及 <a class="reference internal" href="#qt">Qt</a> 是兼容 Python 3 的。</p>
|
||||
<section id="tkinter">
|
||||
<h3><a class="toc-backref" href="#id6">Tkinter</a><a class="headerlink" href="#tkinter" title="永久链接至标题">¶</a></h3>
|
||||
<p>Python 的标准编译包含了 <a class="reference internal" href="../library/tk.html#tkinter"><span class="std std-ref">tkinter</span></a>。这是一个面向对象的接口,指向 Tcl/Tk 微件包。 该接口大概是最容易安装(因为该接口包含在 Python 的大部分 <a class="reference external" href="https://www.python.org/downloads/">二进制发行版</a> 中)和使用的工具包。要了解 Tk 的详情,比如源代码等,可访问 <a class="reference external" href="https://www.tcl.tk">Tcl/Tk 项目主页</a>。 Tcl/Tk 可完整移植至 Mac OS X,Windows 和 Unix 操作系统上。</p>
|
||||
</section>
|
||||
<section id="wxwidgets">
|
||||
<h3><a class="toc-backref" href="#id7">wxWidgets</a><a class="headerlink" href="#wxwidgets" title="永久链接至标题">¶</a></h3>
|
||||
<p>wxWidgets (<a class="reference external" href="https://www.wxwidgets.org">https://www.wxwidgets.org</a>) 是一个自由、可移植的 GUI 图形用户界面类库,使用 C++ 编写。它可以在多个操作系统平台上提供原生自然的界面观感。包括Windows、Mac OS X、 GTK 和 X11 平台在内,都是wxWidgets 当前稳定支持的平台。在语言绑定适配方面,wxWidgets 类库可用于较多语言,包括 Python,Perl,Ruby等。</p>
|
||||
<p><a class="reference external" href="https://www.wxpython.org">wxPython</a> 是 wxWidgets 的 Python 适配。虽然该绑定在更新进度上经常会稍稍落后于 wxWidgets,但它利用纯 Python 扩展,提供了许多其他语言绑定没有实现的特性。wxPython 有一个活跃的用户和开发者社区。</p>
|
||||
<p>wxWidgets 和 wxPython 都是自由开源库。宽松的许可证允许人们在商业软件、自由软件和共享软件中使用它们。</p>
|
||||
</section>
|
||||
<section id="qt">
|
||||
<h3><a class="toc-backref" href="#id8">Qt</a><a class="headerlink" href="#qt" title="永久链接至标题">¶</a></h3>
|
||||
<p>Qt 工具包 (可使用 <a class="reference external" href="https://riverbankcomputing.com/software/pyqt/intro">PyQt</a> 或 <a class="reference external" href="https://wiki.qt.io/PySide">PySide</a>) 及 KDE (<a class="reference external" href="https://techbase.kde.org/Languages/Python/Using_PyKDE_4">PyKDE4</a>) 有多个绑定适配可供选择。 PyQt 当前相较 PySide 更成熟,但如果你想编写专有软件,就必须要从 <a class="reference external" href="https://www.riverbankcomputing.com/commercial/license-faq">Riverbank Computing</a> 购买 PyQt 许可证。 PySide 则可以自由使用于各类软件。</p>
|
||||
<p>Qt 4.5 以上版本使用 LGPL 进行许可;此外,商业许可证可从 <a class="reference external" href="https://www.qt.io/licensing/">Qt 公司</a> 那里获得。</p>
|
||||
</section>
|
||||
<section id="gtk">
|
||||
<h3><a class="toc-backref" href="#id9">Gtk+</a><a class="headerlink" href="#gtk" title="永久链接至标题">¶</a></h3>
|
||||
<p>针对 Python 的 <a class="reference external" href="https://wiki.gnome.org/Projects/PyGObject">GObject 内省绑定</a> 可以用于编写 GTK+ 3 应用。 另请参阅 <a class="reference external" href="https://python-gtk-3-tutorial.readthedocs.io">Python GTK+ 3 教程</a>。</p>
|
||||
<p>更早的、针对 <a class="reference external" href="https://www.gtk.org">Gtk+ 2 工具包</a> 的 PyGtk 绑定,是由 James Henstridge 实现的。具体请参考 <<a class="reference external" href="http://www.pygtk.org">http://www.pygtk.org</a>>。</p>
|
||||
</section>
|
||||
<section id="kivy">
|
||||
<h3><a class="toc-backref" href="#id10">Kivy</a><a class="headerlink" href="#kivy" title="永久链接至标题">¶</a></h3>
|
||||
<p><a class="reference external" href="https://kivy.org/">Kivy</a> 是一种跨平台图形用户界面库,同时支持桌面操作系统(Windows,macOS 和 Linux)以及移动设备(Android,iOS)。该库使用 Python 和 Cython 编写,可以使用一系列窗口后端。</p>
|
||||
<p>Kivy 是自由的开源软件,使用 MIT 许可证分发。</p>
|
||||
</section>
|
||||
<section id="fltk">
|
||||
<h3><a class="toc-backref" href="#id11">FLTK</a><a class="headerlink" href="#fltk" title="永久链接至标题">¶</a></h3>
|
||||
<p><a class="reference external" href="http://www.fltk.org">the FLTK toolkit</a> 的Python绑定是简单却功能强大且成熟的跨平台窗口系统,可以在 <a class="reference external" href="http://pyfltk.sourceforge.net">the PyFLTK project</a> 里获得相关信息。</p>
|
||||
</section>
|
||||
<section id="opengl">
|
||||
<h3><a class="toc-backref" href="#id12">OpenGL</a><a class="headerlink" href="#opengl" title="永久链接至标题">¶</a></h3>
|
||||
<p>对于OpenGL绑定,请参阅 <a class="reference external" href="http://pyopengl.sourceforge.net">PyOpenGL</a>。</p>
|
||||
</section>
|
||||
</section>
|
||||
<section id="what-platform-specific-gui-toolkits-exist-for-python">
|
||||
<h2><a class="toc-backref" href="#id13">有哪些Python的GUI工具是某个平台专用的?</a><a class="headerlink" href="#what-platform-specific-gui-toolkits-exist-for-python" title="永久链接至标题">¶</a></h2>
|
||||
<p>通过安装 <a class="reference external" href="https://pypi.org/project/pyobjc/">PyObjc Objective-C bridge</a>,Python程序可以使用Mac OS X的Cocoa库。</p>
|
||||
<p>Mark Hammond的 <a class="reference internal" href="windows.html#windows-faq"><span class="std std-ref">Pythonwin</span></a> 包括一个微软基础类(MFC)的接口和一个绝大多数由使用MFC类的Python写成的Python编程环境。</p>
|
||||
</section>
|
||||
<section id="tkinter-questions">
|
||||
<h2><a class="toc-backref" href="#id14">有关Tkinter的问题</a><a class="headerlink" href="#tkinter-questions" title="永久链接至标题">¶</a></h2>
|
||||
<section id="how-do-i-freeze-tkinter-applications">
|
||||
<h3><a class="toc-backref" href="#id15">我怎样“冻结”Tkinter程序?</a><a class="headerlink" href="#how-do-i-freeze-tkinter-applications" title="永久链接至标题">¶</a></h3>
|
||||
<p>Freeze (意为 “冻结”)是一个用来创建独立应用程序的工具。 当 “冻结” Tkinter 程序时,程序并不是真的能够独立运行,因为程序仍然需要 Tcl 和 Tk 库。</p>
|
||||
<p>一种解决方法是将程序与 Tcl 和 Tk 库一同发布,并且在运行时使用环境变量 <span class="target" id="index-4"></span><code class="xref std std-envvar docutils literal notranslate"><span class="pre">TCL_LIBRARY</span></code> 和 <span class="target" id="index-5"></span><code class="xref std std-envvar docutils literal notranslate"><span class="pre">TK_LIBRARY</span></code> 指向他们的位置。</p>
|
||||
<p>为了获得真正能独立运行的应用程序,来自库里的 Tcl 脚本也需要被整合进应用程序。 一个做这种事情的工具叫 SAM (stand-alone modules,独立模块) ,它是 Tix distribution (<a class="reference external" href="http://tix.sourceforge.net/">http://tix.sourceforge.net/</a>) 的一部分。</p>
|
||||
<p>在启用 SAM 时编译 Tix ,在 Python 文件 <code class="file docutils literal notranslate"><span class="pre">Modules/tkappinit.c</span></code> 中执行对 <code class="xref c c-func docutils literal notranslate"><span class="pre">Tclsam_init()</span></code> 等的适当调用,并且将程序与 libtclsam 和 libtksam 相链接(可能也要包括 Tix 的库)。</p>
|
||||
</section>
|
||||
<section id="can-i-have-tk-events-handled-while-waiting-for-i-o">
|
||||
<h3><a class="toc-backref" href="#id16">在等待 I/O 操作时能够处理 Tk 事件吗?</a><a class="headerlink" href="#can-i-have-tk-events-handled-while-waiting-for-i-o" title="永久链接至标题">¶</a></h3>
|
||||
<p>在 Windows 以外的其他平台上可以,你甚至不需要使用线程! 但是你必须稍微修改一下你的 I/O 代码。 Tk 有与 Xt 的 <code class="xref c c-func docutils literal notranslate"><span class="pre">XtAddInput()</span></code> 对应的调用,它允许你注册一个回调函数,当一个文件描述符可以进行 I/O 操作的时候,Tk 主循环将会调用这个回调函数。 参见 <a class="reference internal" href="../library/tkinter.html#tkinter-file-handlers"><span class="std std-ref">文件处理程序</span></a>。</p>
|
||||
</section>
|
||||
<section id="i-can-t-get-key-bindings-to-work-in-tkinter-why">
|
||||
<h3><a class="toc-backref" href="#id17">在Tkinter中键绑定不工作:为什么?</a><a class="headerlink" href="#i-can-t-get-key-bindings-to-work-in-tkinter-why" title="永久链接至标题">¶</a></h3>
|
||||
<p>经常听到的抱怨是:已经通过 <code class="xref py py-meth docutils literal notranslate"><span class="pre">bind()</span></code> 方法绑定了事件的处理程序,但是,当按下相关的按键后,这个处理程序却没有执行。</p>
|
||||
<p>最常见的原因是,那个绑定的控件没有“键盘焦点”。请在 Tk 文档中查找 focus 指令。通常一个控件要获得“键盘焦点”,需要点击那个控件(而不是标签;请查看 takefocus 选项)。</p>
|
||||
</section>
|
||||
</section>
|
||||
</section>
|
||||
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="sphinxsidebar" role="navigation" aria-label="main navigation">
|
||||
<div class="sphinxsidebarwrapper">
|
||||
<h3><a href="../contents.html">目录</a></h3>
|
||||
<ul>
|
||||
<li><a class="reference internal" href="#">图形用户界面(GUI)常见问题</a><ul>
|
||||
<li><a class="reference internal" href="#general-gui-questions">图形界面常见问题</a></li>
|
||||
<li><a class="reference internal" href="#what-platform-independent-gui-toolkits-exist-for-python">Python 是否有平台无关的图形界面工具包?</a></li>
|
||||
<li><a class="reference internal" href="#what-platform-specific-gui-toolkits-exist-for-python">有哪些Python的GUI工具是某个平台专用的?</a></li>
|
||||
<li><a class="reference internal" href="#tkinter-questions">有关Tkinter的问题</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<h4>上一个主题</h4>
|
||||
<p class="topless"><a href="windows.html"
|
||||
title="上一章">Python在Windows上的常见问题</a></p>
|
||||
<h4>下一个主题</h4>
|
||||
<p class="topless"><a href="installed.html"
|
||||
title="下一章">“为什么我的电脑上安装了 Python ?”</a></p>
|
||||
<div role="note" aria-label="source link">
|
||||
<h3>本页</h3>
|
||||
<ul class="this-page-menu">
|
||||
<li><a href="../bugs.html">报告 Bug</a></li>
|
||||
<li>
|
||||
<a href="https://github.com/python/cpython/blob/3.8/Doc/faq/gui.rst"
|
||||
rel="nofollow">显示源代码
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="clearer"></div>
|
||||
</div>
|
||||
<div class="related" role="navigation" aria-label="related navigation">
|
||||
<h3>导航</h3>
|
||||
<ul>
|
||||
<li class="right" style="margin-right: 10px">
|
||||
<a href="../genindex.html" title="总目录"
|
||||
>索引</a></li>
|
||||
<li class="right" >
|
||||
<a href="../py-modindex.html" title="Python 模块索引"
|
||||
>模块</a> |</li>
|
||||
<li class="right" >
|
||||
<a href="installed.html" title="“为什么我的电脑上安装了 Python ?”"
|
||||
>下一页</a> |</li>
|
||||
<li class="right" >
|
||||
<a href="windows.html" title="Python在Windows上的常见问题"
|
||||
>上一页</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.8.20 Documentation</a> »
|
||||
</li>
|
||||
|
||||
<li class="nav-item nav-item-1"><a href="index.html" >Python 常见问题</a> »</li>
|
||||
<li class="right">
|
||||
|
||||
|
||||
<div class="inline-search" role="search">
|
||||
<form class="inline-search" action="../search.html" method="get">
|
||||
<input placeholder="快速搜索" aria-label="快速搜索" type="text" name="q" />
|
||||
<input type="submit" value="转向" />
|
||||
<input type="hidden" name="check_keywords" value="yes" />
|
||||
<input type="hidden" name="area" value="default" />
|
||||
</form>
|
||||
</div>
|
||||
|
|
||||
</li>
|
||||
|
||||
</ul>
|
||||
</div>
|
||||
<div class="footer">
|
||||
© <a href="../copyright.html">版权所有</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 />
|
||||
|
||||
<br />
|
||||
|
||||
The Python Software Foundation is a non-profit corporation.
|
||||
<a href="https://www.python.org/psf/donations/">Please donate.</a>
|
||||
<br />
|
||||
<br />
|
||||
|
||||
最后更新于 12月 09, 2024.
|
||||
<a href="https://docs.python.org/3/bugs.html">Found a bug</a>?
|
||||
<br />
|
||||
|
||||
Created using <a href="https://www.sphinx-doc.org/">Sphinx</a> 2.4.4.
|
||||
</div>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
262
web/python-docs/faq/index.html
Normal file
262
web/python-docs/faq/index.html
Normal file
@@ -0,0 +1,262 @@
|
||||
|
||||
<!DOCTYPE html>
|
||||
|
||||
<html xmlns="http://www.w3.org/1999/xhtml" lang="zh_CN">
|
||||
<head>
|
||||
<meta charset="utf-8" /><meta name="generator" content="Docutils 0.17.1: http://docutils.sourceforge.net/" />
|
||||
|
||||
<title>Python 常见问题 — Python 3.8.20 文档</title><meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
|
||||
<link rel="stylesheet" href="../_static/pydoctheme.css" type="text/css" />
|
||||
<link rel="stylesheet" href="../_static/pygments.css" type="text/css" />
|
||||
|
||||
<script id="documentation_options" data-url_root="../" src="../_static/documentation_options.js"></script>
|
||||
<script src="../_static/jquery.js"></script>
|
||||
<script src="../_static/underscore.js"></script>
|
||||
<script src="../_static/doctools.js"></script>
|
||||
<script src="../_static/language_data.js"></script>
|
||||
<script src="../_static/translations.js"></script>
|
||||
|
||||
<script src="../_static/sidebar.js"></script>
|
||||
|
||||
<link rel="search" type="application/opensearchdescription+xml"
|
||||
title="在 Python 3.8.20 文档 中搜索"
|
||||
href="../_static/opensearch.xml"/>
|
||||
<link rel="author" title="关于这些文档" href="../about.html" />
|
||||
<link rel="index" title="索引" href="../genindex.html" />
|
||||
<link rel="search" title="搜索" href="../search.html" />
|
||||
<link rel="copyright" title="版权所有" href="../copyright.html" />
|
||||
<link rel="next" title="Python常见问题" href="general.html" />
|
||||
<link rel="prev" title="使用 DTrace 和 SystemTap 检测CPython" href="../howto/instrumentation.html" />
|
||||
<link rel="canonical" href="https://docs.python.org/3/faq/index.html" />
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<style>
|
||||
@media only screen {
|
||||
table.full-width-table {
|
||||
width: 100%;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
<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>
|
||||
|
||||
</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" />
|
||||
<label for="menuToggler" class="toggler__label">
|
||||
<span></span>
|
||||
</label>
|
||||
<nav class="nav-content" role="navigation">
|
||||
<a href="https://www.python.org/" class="nav-logo">
|
||||
<img src="../_static/py.svg" alt="Logo"/>
|
||||
</a>
|
||||
<div class="version_switcher_placeholder"></div>
|
||||
<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"
|
||||
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" fill="#444"></path>
|
||||
</svg>
|
||||
<input type="text" name="q" aria-label="快速搜索"/>
|
||||
<input type="submit" value="转向"/>
|
||||
</form>
|
||||
</nav>
|
||||
<div class="menu-wrapper">
|
||||
<nav class="menu" role="navigation" aria-label="main navigation">
|
||||
<div class="language_switcher_placeholder"></div>
|
||||
<h4>上一个主题</h4>
|
||||
<p class="topless"><a href="../howto/instrumentation.html"
|
||||
title="上一章">使用 DTrace 和 SystemTap 检测CPython</a></p>
|
||||
<h4>下一个主题</h4>
|
||||
<p class="topless"><a href="general.html"
|
||||
title="下一章">Python常见问题</a></p>
|
||||
<div role="note" aria-label="source link">
|
||||
<h3>本页</h3>
|
||||
<ul class="this-page-menu">
|
||||
<li><a href="../bugs.html">报告 Bug</a></li>
|
||||
<li>
|
||||
<a href="https://github.com/python/cpython/blob/3.8/Doc/faq/index.rst"
|
||||
rel="nofollow">显示源代码
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</nav>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="outdated-warning" style="padding: .5em; text-align: center; background-color: #FFBABA; color: #6A0E0E;">
|
||||
这个文档所针对的是一个已不再受支持的 Python 旧版本。
|
||||
你应当升级版本,并阅读
|
||||
<a href="/3/faq/index.html"> Python 当前稳定版本的文档</a>.
|
||||
</div>
|
||||
|
||||
<div class="related" role="navigation" aria-label="related navigation">
|
||||
<h3>导航</h3>
|
||||
<ul>
|
||||
<li class="right" style="margin-right: 10px">
|
||||
<a href="../genindex.html" title="总目录"
|
||||
accesskey="I">索引</a></li>
|
||||
<li class="right" >
|
||||
<a href="../py-modindex.html" title="Python 模块索引"
|
||||
>模块</a> |</li>
|
||||
<li class="right" >
|
||||
<a href="general.html" title="Python常见问题"
|
||||
accesskey="N">下一页</a> |</li>
|
||||
<li class="right" >
|
||||
<a href="../howto/instrumentation.html" title="使用 DTrace 和 SystemTap 检测CPython"
|
||||
accesskey="P">上一页</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.8.20 Documentation</a> »
|
||||
</li>
|
||||
|
||||
<li class="right">
|
||||
|
||||
|
||||
<div class="inline-search" role="search">
|
||||
<form class="inline-search" action="../search.html" method="get">
|
||||
<input placeholder="快速搜索" aria-label="快速搜索" type="text" name="q" />
|
||||
<input type="submit" value="转向" />
|
||||
<input type="hidden" name="check_keywords" value="yes" />
|
||||
<input type="hidden" name="area" value="default" />
|
||||
</form>
|
||||
</div>
|
||||
|
|
||||
</li>
|
||||
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<div class="document">
|
||||
<div class="documentwrapper">
|
||||
<div class="bodywrapper">
|
||||
<div class="body" role="main">
|
||||
|
||||
<section id="python-frequently-asked-questions">
|
||||
<span id="faq-index"></span><h1>Python 常见问题<a class="headerlink" href="#python-frequently-asked-questions" title="永久链接至标题">¶</a></h1>
|
||||
<div class="toctree-wrapper compound">
|
||||
<ul>
|
||||
<li class="toctree-l1"><a class="reference internal" href="general.html">Python常见问题</a></li>
|
||||
<li class="toctree-l1"><a class="reference internal" href="programming.html">编程常见问题</a></li>
|
||||
<li class="toctree-l1"><a class="reference internal" href="design.html">设计和历史常见问题</a></li>
|
||||
<li class="toctree-l1"><a class="reference internal" href="library.html">代码库和插件 FAQ</a></li>
|
||||
<li class="toctree-l1"><a class="reference internal" href="extending.html">扩展/嵌入常见问题</a></li>
|
||||
<li class="toctree-l1"><a class="reference internal" href="windows.html">Python在Windows上的常见问题</a></li>
|
||||
<li class="toctree-l1"><a class="reference internal" href="gui.html">图形用户界面(GUI)常见问题</a></li>
|
||||
<li class="toctree-l1"><a class="reference internal" href="installed.html">“为什么我的电脑上安装了 Python ?”</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="sphinxsidebar" role="navigation" aria-label="main navigation">
|
||||
<div class="sphinxsidebarwrapper">
|
||||
<h4>上一个主题</h4>
|
||||
<p class="topless"><a href="../howto/instrumentation.html"
|
||||
title="上一章">使用 DTrace 和 SystemTap 检测CPython</a></p>
|
||||
<h4>下一个主题</h4>
|
||||
<p class="topless"><a href="general.html"
|
||||
title="下一章">Python常见问题</a></p>
|
||||
<div role="note" aria-label="source link">
|
||||
<h3>本页</h3>
|
||||
<ul class="this-page-menu">
|
||||
<li><a href="../bugs.html">报告 Bug</a></li>
|
||||
<li>
|
||||
<a href="https://github.com/python/cpython/blob/3.8/Doc/faq/index.rst"
|
||||
rel="nofollow">显示源代码
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="clearer"></div>
|
||||
</div>
|
||||
<div class="related" role="navigation" aria-label="related navigation">
|
||||
<h3>导航</h3>
|
||||
<ul>
|
||||
<li class="right" style="margin-right: 10px">
|
||||
<a href="../genindex.html" title="总目录"
|
||||
>索引</a></li>
|
||||
<li class="right" >
|
||||
<a href="../py-modindex.html" title="Python 模块索引"
|
||||
>模块</a> |</li>
|
||||
<li class="right" >
|
||||
<a href="general.html" title="Python常见问题"
|
||||
>下一页</a> |</li>
|
||||
<li class="right" >
|
||||
<a href="../howto/instrumentation.html" title="使用 DTrace 和 SystemTap 检测CPython"
|
||||
>上一页</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.8.20 Documentation</a> »
|
||||
</li>
|
||||
|
||||
<li class="right">
|
||||
|
||||
|
||||
<div class="inline-search" role="search">
|
||||
<form class="inline-search" action="../search.html" method="get">
|
||||
<input placeholder="快速搜索" aria-label="快速搜索" type="text" name="q" />
|
||||
<input type="submit" value="转向" />
|
||||
<input type="hidden" name="check_keywords" value="yes" />
|
||||
<input type="hidden" name="area" value="default" />
|
||||
</form>
|
||||
</div>
|
||||
|
|
||||
</li>
|
||||
|
||||
</ul>
|
||||
</div>
|
||||
<div class="footer">
|
||||
© <a href="../copyright.html">版权所有</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 />
|
||||
|
||||
<br />
|
||||
|
||||
The Python Software Foundation is a non-profit corporation.
|
||||
<a href="https://www.python.org/psf/donations/">Please donate.</a>
|
||||
<br />
|
||||
<br />
|
||||
|
||||
最后更新于 12月 09, 2024.
|
||||
<a href="https://docs.python.org/3/bugs.html">Found a bug</a>?
|
||||
<br />
|
||||
|
||||
Created using <a href="https://www.sphinx-doc.org/">Sphinx</a> 2.4.4.
|
||||
</div>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
294
web/python-docs/faq/installed.html
Normal file
294
web/python-docs/faq/installed.html
Normal file
@@ -0,0 +1,294 @@
|
||||
|
||||
<!DOCTYPE html>
|
||||
|
||||
<html xmlns="http://www.w3.org/1999/xhtml" lang="zh_CN">
|
||||
<head>
|
||||
<meta charset="utf-8" /><meta name="generator" content="Docutils 0.17.1: http://docutils.sourceforge.net/" />
|
||||
|
||||
<title>“为什么我的电脑上安装了 Python ?” — Python 3.8.20 文档</title><meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
|
||||
<link rel="stylesheet" href="../_static/pydoctheme.css" type="text/css" />
|
||||
<link rel="stylesheet" href="../_static/pygments.css" type="text/css" />
|
||||
|
||||
<script id="documentation_options" data-url_root="../" src="../_static/documentation_options.js"></script>
|
||||
<script src="../_static/jquery.js"></script>
|
||||
<script src="../_static/underscore.js"></script>
|
||||
<script src="../_static/doctools.js"></script>
|
||||
<script src="../_static/language_data.js"></script>
|
||||
<script src="../_static/translations.js"></script>
|
||||
|
||||
<script src="../_static/sidebar.js"></script>
|
||||
|
||||
<link rel="search" type="application/opensearchdescription+xml"
|
||||
title="在 Python 3.8.20 文档 中搜索"
|
||||
href="../_static/opensearch.xml"/>
|
||||
<link rel="author" title="关于这些文档" href="../about.html" />
|
||||
<link rel="index" title="索引" href="../genindex.html" />
|
||||
<link rel="search" title="搜索" href="../search.html" />
|
||||
<link rel="copyright" title="版权所有" href="../copyright.html" />
|
||||
<link rel="next" title="术语对照表" href="../glossary.html" />
|
||||
<link rel="prev" title="图形用户界面(GUI)常见问题" href="gui.html" />
|
||||
<link rel="canonical" href="https://docs.python.org/3/faq/installed.html" />
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<style>
|
||||
@media only screen {
|
||||
table.full-width-table {
|
||||
width: 100%;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
<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>
|
||||
|
||||
</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" />
|
||||
<label for="menuToggler" class="toggler__label">
|
||||
<span></span>
|
||||
</label>
|
||||
<nav class="nav-content" role="navigation">
|
||||
<a href="https://www.python.org/" class="nav-logo">
|
||||
<img src="../_static/py.svg" alt="Logo"/>
|
||||
</a>
|
||||
<div class="version_switcher_placeholder"></div>
|
||||
<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"
|
||||
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" fill="#444"></path>
|
||||
</svg>
|
||||
<input type="text" name="q" aria-label="快速搜索"/>
|
||||
<input type="submit" value="转向"/>
|
||||
</form>
|
||||
</nav>
|
||||
<div class="menu-wrapper">
|
||||
<nav class="menu" role="navigation" aria-label="main navigation">
|
||||
<div class="language_switcher_placeholder"></div>
|
||||
<h3><a href="../contents.html">目录</a></h3>
|
||||
<ul>
|
||||
<li><a class="reference internal" href="#">“为什么我的电脑上安装了 Python ?”</a><ul>
|
||||
<li><a class="reference internal" href="#what-is-python">什么是 Python?</a></li>
|
||||
<li><a class="reference internal" href="#why-is-python-installed-on-my-machine">为什么我的电脑上安装了 Python ?</a></li>
|
||||
<li><a class="reference internal" href="#can-i-delete-python">我能删除 Python 吗?</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<h4>上一个主题</h4>
|
||||
<p class="topless"><a href="gui.html"
|
||||
title="上一章">图形用户界面(GUI)常见问题</a></p>
|
||||
<h4>下一个主题</h4>
|
||||
<p class="topless"><a href="../glossary.html"
|
||||
title="下一章">术语对照表</a></p>
|
||||
<div role="note" aria-label="source link">
|
||||
<h3>本页</h3>
|
||||
<ul class="this-page-menu">
|
||||
<li><a href="../bugs.html">报告 Bug</a></li>
|
||||
<li>
|
||||
<a href="https://github.com/python/cpython/blob/3.8/Doc/faq/installed.rst"
|
||||
rel="nofollow">显示源代码
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</nav>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="outdated-warning" style="padding: .5em; text-align: center; background-color: #FFBABA; color: #6A0E0E;">
|
||||
这个文档所针对的是一个已不再受支持的 Python 旧版本。
|
||||
你应当升级版本,并阅读
|
||||
<a href="/3/faq/installed.html"> Python 当前稳定版本的文档</a>.
|
||||
</div>
|
||||
|
||||
<div class="related" role="navigation" aria-label="related navigation">
|
||||
<h3>导航</h3>
|
||||
<ul>
|
||||
<li class="right" style="margin-right: 10px">
|
||||
<a href="../genindex.html" title="总目录"
|
||||
accesskey="I">索引</a></li>
|
||||
<li class="right" >
|
||||
<a href="../py-modindex.html" title="Python 模块索引"
|
||||
>模块</a> |</li>
|
||||
<li class="right" >
|
||||
<a href="../glossary.html" title="术语对照表"
|
||||
accesskey="N">下一页</a> |</li>
|
||||
<li class="right" >
|
||||
<a href="gui.html" title="图形用户界面(GUI)常见问题"
|
||||
accesskey="P">上一页</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.8.20 Documentation</a> »
|
||||
</li>
|
||||
|
||||
<li class="nav-item nav-item-1"><a href="index.html" accesskey="U">Python 常见问题</a> »</li>
|
||||
<li class="right">
|
||||
|
||||
|
||||
<div class="inline-search" role="search">
|
||||
<form class="inline-search" action="../search.html" method="get">
|
||||
<input placeholder="快速搜索" aria-label="快速搜索" type="text" name="q" />
|
||||
<input type="submit" value="转向" />
|
||||
<input type="hidden" name="check_keywords" value="yes" />
|
||||
<input type="hidden" name="area" value="default" />
|
||||
</form>
|
||||
</div>
|
||||
|
|
||||
</li>
|
||||
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<div class="document">
|
||||
<div class="documentwrapper">
|
||||
<div class="bodywrapper">
|
||||
<div class="body" role="main">
|
||||
|
||||
<section id="why-is-python-installed-on-my-computer-faq">
|
||||
<h1>“为什么我的电脑上安装了 Python ?”<a class="headerlink" href="#why-is-python-installed-on-my-computer-faq" title="永久链接至标题">¶</a></h1>
|
||||
<section id="what-is-python">
|
||||
<h2>什么是 Python?<a class="headerlink" href="#what-is-python" title="永久链接至标题">¶</a></h2>
|
||||
<p>Python 是一种程序语言,被许多应用程序使用。它不仅因易学而在许多高校用于编程入门,还被工作于 Google、NASA 和卢卡斯影业等公司的软件开发人员使用。</p>
|
||||
<p>如果你想学习更多 Python,看看 <a class="reference external" href="https://wiki.python.org/moin/BeginnersGuide">Beginner's Guide to Python</a>.</p>
|
||||
</section>
|
||||
<section id="why-is-python-installed-on-my-machine">
|
||||
<h2>为什么我的电脑上安装了 Python ?<a class="headerlink" href="#why-is-python-installed-on-my-machine" title="永久链接至标题">¶</a></h2>
|
||||
<p>如果你不记得你曾主动安装过 Python,但它却出现在了你的电脑上,这里有一些可能的原因。</p>
|
||||
<ul class="simple">
|
||||
<li><p>可能是这台电脑的其他用户因想学习编程而安装了它,你得琢磨一下谁用过这台电脑并安装了 Python。</p></li>
|
||||
<li><p>电脑上安装的第三方应用程序可能由 Python 写成并附带了一份 Python。这样的应用程序有很多,例如GUI程序、网络服务器、管理脚本等。</p></li>
|
||||
<li><p>一些 Windows 可能预装了 Python。在撰写本文时,我们了解到 Hewlett-Packard 和 Compaq 的计算机包含Python。显然,HP/Compaq 的一些管理工具是用 Python 编写的。</p></li>
|
||||
<li><p>许多 Unix 兼容的操作系统,例如 Mac OS X 和一些 Linux 发行版,默认安装了Python;它被包含在基本安装套件中。</p></li>
|
||||
</ul>
|
||||
</section>
|
||||
<section id="can-i-delete-python">
|
||||
<h2>我能删除 Python 吗?<a class="headerlink" href="#can-i-delete-python" title="永久链接至标题">¶</a></h2>
|
||||
<p>这取决于所安装 Python 的来源</p>
|
||||
<p>如果有人主动安装了 Python,你可以在不影响其它程序的情况下安全移除它。在 Windows 中,可使用“控制面板”中的“添加/删除程序”卸载。</p>
|
||||
<p>如果 Python 来源于第三方应用程序,你也能删除它,但那些程序将不能正常工作。你应该使用那些应用程序的卸载器而不是直接删除 Python。</p>
|
||||
<p>如果 Python 来自于你的操作系统,不推荐删除!如果删除了它,任何用 Python 写成的工具将无法工作,其中某些工具对于你来说可能十分重要。你甚至可能需要重装整个系统来修复因删除 Python 留下的烂摊子。</p>
|
||||
</section>
|
||||
</section>
|
||||
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="sphinxsidebar" role="navigation" aria-label="main navigation">
|
||||
<div class="sphinxsidebarwrapper">
|
||||
<h3><a href="../contents.html">目录</a></h3>
|
||||
<ul>
|
||||
<li><a class="reference internal" href="#">“为什么我的电脑上安装了 Python ?”</a><ul>
|
||||
<li><a class="reference internal" href="#what-is-python">什么是 Python?</a></li>
|
||||
<li><a class="reference internal" href="#why-is-python-installed-on-my-machine">为什么我的电脑上安装了 Python ?</a></li>
|
||||
<li><a class="reference internal" href="#can-i-delete-python">我能删除 Python 吗?</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<h4>上一个主题</h4>
|
||||
<p class="topless"><a href="gui.html"
|
||||
title="上一章">图形用户界面(GUI)常见问题</a></p>
|
||||
<h4>下一个主题</h4>
|
||||
<p class="topless"><a href="../glossary.html"
|
||||
title="下一章">术语对照表</a></p>
|
||||
<div role="note" aria-label="source link">
|
||||
<h3>本页</h3>
|
||||
<ul class="this-page-menu">
|
||||
<li><a href="../bugs.html">报告 Bug</a></li>
|
||||
<li>
|
||||
<a href="https://github.com/python/cpython/blob/3.8/Doc/faq/installed.rst"
|
||||
rel="nofollow">显示源代码
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="clearer"></div>
|
||||
</div>
|
||||
<div class="related" role="navigation" aria-label="related navigation">
|
||||
<h3>导航</h3>
|
||||
<ul>
|
||||
<li class="right" style="margin-right: 10px">
|
||||
<a href="../genindex.html" title="总目录"
|
||||
>索引</a></li>
|
||||
<li class="right" >
|
||||
<a href="../py-modindex.html" title="Python 模块索引"
|
||||
>模块</a> |</li>
|
||||
<li class="right" >
|
||||
<a href="../glossary.html" title="术语对照表"
|
||||
>下一页</a> |</li>
|
||||
<li class="right" >
|
||||
<a href="gui.html" title="图形用户界面(GUI)常见问题"
|
||||
>上一页</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.8.20 Documentation</a> »
|
||||
</li>
|
||||
|
||||
<li class="nav-item nav-item-1"><a href="index.html" >Python 常见问题</a> »</li>
|
||||
<li class="right">
|
||||
|
||||
|
||||
<div class="inline-search" role="search">
|
||||
<form class="inline-search" action="../search.html" method="get">
|
||||
<input placeholder="快速搜索" aria-label="快速搜索" type="text" name="q" />
|
||||
<input type="submit" value="转向" />
|
||||
<input type="hidden" name="check_keywords" value="yes" />
|
||||
<input type="hidden" name="area" value="default" />
|
||||
</form>
|
||||
</div>
|
||||
|
|
||||
</li>
|
||||
|
||||
</ul>
|
||||
</div>
|
||||
<div class="footer">
|
||||
© <a href="../copyright.html">版权所有</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 />
|
||||
|
||||
<br />
|
||||
|
||||
The Python Software Foundation is a non-profit corporation.
|
||||
<a href="https://www.python.org/psf/donations/">Please donate.</a>
|
||||
<br />
|
||||
<br />
|
||||
|
||||
最后更新于 12月 09, 2024.
|
||||
<a href="https://docs.python.org/3/bugs.html">Found a bug</a>?
|
||||
<br />
|
||||
|
||||
Created using <a href="https://www.sphinx-doc.org/">Sphinx</a> 2.4.4.
|
||||
</div>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
772
web/python-docs/faq/library.html
Normal file
772
web/python-docs/faq/library.html
Normal file
@@ -0,0 +1,772 @@
|
||||
|
||||
<!DOCTYPE html>
|
||||
|
||||
<html xmlns="http://www.w3.org/1999/xhtml" lang="zh_CN">
|
||||
<head>
|
||||
<meta charset="utf-8" /><meta name="generator" content="Docutils 0.17.1: http://docutils.sourceforge.net/" />
|
||||
|
||||
<title>代码库和插件 FAQ — Python 3.8.20 文档</title><meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
|
||||
<link rel="stylesheet" href="../_static/pydoctheme.css" type="text/css" />
|
||||
<link rel="stylesheet" href="../_static/pygments.css" type="text/css" />
|
||||
|
||||
<script id="documentation_options" data-url_root="../" src="../_static/documentation_options.js"></script>
|
||||
<script src="../_static/jquery.js"></script>
|
||||
<script src="../_static/underscore.js"></script>
|
||||
<script src="../_static/doctools.js"></script>
|
||||
<script src="../_static/language_data.js"></script>
|
||||
<script src="../_static/translations.js"></script>
|
||||
|
||||
<script src="../_static/sidebar.js"></script>
|
||||
|
||||
<link rel="search" type="application/opensearchdescription+xml"
|
||||
title="在 Python 3.8.20 文档 中搜索"
|
||||
href="../_static/opensearch.xml"/>
|
||||
<link rel="author" title="关于这些文档" href="../about.html" />
|
||||
<link rel="index" title="索引" href="../genindex.html" />
|
||||
<link rel="search" title="搜索" href="../search.html" />
|
||||
<link rel="copyright" title="版权所有" href="../copyright.html" />
|
||||
<link rel="next" title="扩展/嵌入常见问题" href="extending.html" />
|
||||
<link rel="prev" title="设计和历史常见问题" href="design.html" />
|
||||
<link rel="canonical" href="https://docs.python.org/3/faq/library.html" />
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<style>
|
||||
@media only screen {
|
||||
table.full-width-table {
|
||||
width: 100%;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
<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>
|
||||
|
||||
</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" />
|
||||
<label for="menuToggler" class="toggler__label">
|
||||
<span></span>
|
||||
</label>
|
||||
<nav class="nav-content" role="navigation">
|
||||
<a href="https://www.python.org/" class="nav-logo">
|
||||
<img src="../_static/py.svg" alt="Logo"/>
|
||||
</a>
|
||||
<div class="version_switcher_placeholder"></div>
|
||||
<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"
|
||||
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" fill="#444"></path>
|
||||
</svg>
|
||||
<input type="text" name="q" aria-label="快速搜索"/>
|
||||
<input type="submit" value="转向"/>
|
||||
</form>
|
||||
</nav>
|
||||
<div class="menu-wrapper">
|
||||
<nav class="menu" role="navigation" aria-label="main navigation">
|
||||
<div class="language_switcher_placeholder"></div>
|
||||
<h3><a href="../contents.html">目录</a></h3>
|
||||
<ul>
|
||||
<li><a class="reference internal" href="#">代码库和插件 FAQ</a><ul>
|
||||
<li><a class="reference internal" href="#general-library-questions">通用的代码库问题</a></li>
|
||||
<li><a class="reference internal" href="#common-tasks">通用任务</a></li>
|
||||
<li><a class="reference internal" href="#threads">线程相关</a></li>
|
||||
<li><a class="reference internal" href="#input-and-output">输入输出</a></li>
|
||||
<li><a class="reference internal" href="#network-internet-programming">网络 / Internet 编程</a></li>
|
||||
<li><a class="reference internal" href="#databases">数据库</a></li>
|
||||
<li><a class="reference internal" href="#mathematics-and-numerics">数学和数字</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<h4>上一个主题</h4>
|
||||
<p class="topless"><a href="design.html"
|
||||
title="上一章">设计和历史常见问题</a></p>
|
||||
<h4>下一个主题</h4>
|
||||
<p class="topless"><a href="extending.html"
|
||||
title="下一章">扩展/嵌入常见问题</a></p>
|
||||
<div role="note" aria-label="source link">
|
||||
<h3>本页</h3>
|
||||
<ul class="this-page-menu">
|
||||
<li><a href="../bugs.html">报告 Bug</a></li>
|
||||
<li>
|
||||
<a href="https://github.com/python/cpython/blob/3.8/Doc/faq/library.rst"
|
||||
rel="nofollow">显示源代码
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</nav>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="outdated-warning" style="padding: .5em; text-align: center; background-color: #FFBABA; color: #6A0E0E;">
|
||||
这个文档所针对的是一个已不再受支持的 Python 旧版本。
|
||||
你应当升级版本,并阅读
|
||||
<a href="/3/faq/library.html"> Python 当前稳定版本的文档</a>.
|
||||
</div>
|
||||
|
||||
<div class="related" role="navigation" aria-label="related navigation">
|
||||
<h3>导航</h3>
|
||||
<ul>
|
||||
<li class="right" style="margin-right: 10px">
|
||||
<a href="../genindex.html" title="总目录"
|
||||
accesskey="I">索引</a></li>
|
||||
<li class="right" >
|
||||
<a href="../py-modindex.html" title="Python 模块索引"
|
||||
>模块</a> |</li>
|
||||
<li class="right" >
|
||||
<a href="extending.html" title="扩展/嵌入常见问题"
|
||||
accesskey="N">下一页</a> |</li>
|
||||
<li class="right" >
|
||||
<a href="design.html" title="设计和历史常见问题"
|
||||
accesskey="P">上一页</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.8.20 Documentation</a> »
|
||||
</li>
|
||||
|
||||
<li class="nav-item nav-item-1"><a href="index.html" accesskey="U">Python 常见问题</a> »</li>
|
||||
<li class="right">
|
||||
|
||||
|
||||
<div class="inline-search" role="search">
|
||||
<form class="inline-search" action="../search.html" method="get">
|
||||
<input placeholder="快速搜索" aria-label="快速搜索" type="text" name="q" />
|
||||
<input type="submit" value="转向" />
|
||||
<input type="hidden" name="check_keywords" value="yes" />
|
||||
<input type="hidden" name="area" value="default" />
|
||||
</form>
|
||||
</div>
|
||||
|
|
||||
</li>
|
||||
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<div class="document">
|
||||
<div class="documentwrapper">
|
||||
<div class="bodywrapper">
|
||||
<div class="body" role="main">
|
||||
|
||||
<section id="library-and-extension-faq">
|
||||
<h1><a class="toc-backref" href="#id2">代码库和插件 FAQ</a><a class="headerlink" href="#library-and-extension-faq" title="永久链接至标题">¶</a></h1>
|
||||
<div class="contents topic" id="id1">
|
||||
<p class="topic-title">目录</p>
|
||||
<ul class="simple">
|
||||
<li><p><a class="reference internal" href="#library-and-extension-faq" id="id2">代码库和插件 FAQ</a></p>
|
||||
<ul>
|
||||
<li><p><a class="reference internal" href="#general-library-questions" id="id3">通用的代码库问题</a></p>
|
||||
<ul>
|
||||
<li><p><a class="reference internal" href="#how-do-i-find-a-module-or-application-to-perform-task-x" id="id4">如何找到可以用来做 XXX 的模块或应用?</a></p></li>
|
||||
<li><p><a class="reference internal" href="#where-is-the-math-py-socket-py-regex-py-etc-source-file" id="id5">math.py(socket.py,regex.py 等)的源文件在哪?</a></p></li>
|
||||
<li><p><a class="reference internal" href="#how-do-i-make-a-python-script-executable-on-unix" id="id6">在 Unix 中怎样让 Python 脚本可执行?</a></p></li>
|
||||
<li><p><a class="reference internal" href="#is-there-a-curses-termcap-package-for-python" id="id7">Python 中有 curses/termcap 包吗?</a></p></li>
|
||||
<li><p><a class="reference internal" href="#is-there-an-equivalent-to-c-s-onexit-in-python" id="id8">Python 中存在类似 C 的 onexit() 函数的东西吗?</a></p></li>
|
||||
<li><p><a class="reference internal" href="#why-don-t-my-signal-handlers-work" id="id9">为什么我的信号处理函数不能工作?</a></p></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li><p><a class="reference internal" href="#common-tasks" id="id10">通用任务</a></p>
|
||||
<ul>
|
||||
<li><p><a class="reference internal" href="#how-do-i-test-a-python-program-or-component" id="id11">怎样测试 Python 程序或组件?</a></p></li>
|
||||
<li><p><a class="reference internal" href="#how-do-i-create-documentation-from-doc-strings" id="id12">怎样用 docstring 创建文档?</a></p></li>
|
||||
<li><p><a class="reference internal" href="#how-do-i-get-a-single-keypress-at-a-time" id="id13">怎样一次只获取一个按键?</a></p></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li><p><a class="reference internal" href="#threads" id="id14">线程相关</a></p>
|
||||
<ul>
|
||||
<li><p><a class="reference internal" href="#how-do-i-program-using-threads" id="id15">程序中怎样使用线程?</a></p></li>
|
||||
<li><p><a class="reference internal" href="#none-of-my-threads-seem-to-run-why" id="id16">我的线程都没有运行,为什么?</a></p></li>
|
||||
<li><p><a class="reference internal" href="#how-do-i-parcel-out-work-among-a-bunch-of-worker-threads" id="id17">如何将任务分配给多个工作线程?</a></p></li>
|
||||
<li><p><a class="reference internal" href="#what-kinds-of-global-value-mutation-are-thread-safe" id="id18">怎样修改全局变量是线程安全的?</a></p></li>
|
||||
<li><p><a class="reference internal" href="#can-t-we-get-rid-of-the-global-interpreter-lock" id="id19">不能删除全局解释器锁吗?</a></p></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li><p><a class="reference internal" href="#input-and-output" id="id20">输入输出</a></p>
|
||||
<ul>
|
||||
<li><p><a class="reference internal" href="#how-do-i-delete-a-file-and-other-file-questions" id="id21">怎样删除文件?(以及其他文件相关的问题……)</a></p></li>
|
||||
<li><p><a class="reference internal" href="#how-do-i-copy-a-file" id="id22">怎样复制文件?</a></p></li>
|
||||
<li><p><a class="reference internal" href="#how-do-i-read-or-write-binary-data" id="id23">怎样读取(或写入)二进制数据?</a></p></li>
|
||||
<li><p><a class="reference internal" href="#i-can-t-seem-to-use-os-read-on-a-pipe-created-with-os-popen-why" id="id24">似乎 os.popen() 创建的管道不能使用 os.read(),这是为什么?</a></p></li>
|
||||
<li><p><a class="reference internal" href="#how-do-i-access-the-serial-rs232-port" id="id25">怎样访问(RS232)串口?</a></p></li>
|
||||
<li><p><a class="reference internal" href="#why-doesn-t-closing-sys-stdout-stdin-stderr-really-close-it" id="id26">为什么关闭 sys.stdout(stdin,stderr)并不会真正关掉它?</a></p></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li><p><a class="reference internal" href="#network-internet-programming" id="id27">网络 / Internet 编程</a></p>
|
||||
<ul>
|
||||
<li><p><a class="reference internal" href="#what-www-tools-are-there-for-python" id="id28">Python 中的 WWW 工具是什么?</a></p></li>
|
||||
<li><p><a class="reference internal" href="#how-can-i-mimic-cgi-form-submission-method-post" id="id29">怎样模拟发送 CGI 表单(METHOD=POST)?</a></p></li>
|
||||
<li><p><a class="reference internal" href="#what-module-should-i-use-to-help-with-generating-html" id="id30">生成 HTML 需要使用什么模块?</a></p></li>
|
||||
<li><p><a class="reference internal" href="#how-do-i-send-mail-from-a-python-script" id="id31">怎样使用 Python 脚本发送邮件?</a></p></li>
|
||||
<li><p><a class="reference internal" href="#how-do-i-avoid-blocking-in-the-connect-method-of-a-socket" id="id32">socket 的 connect() 方法怎样避免阻塞?</a></p></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li><p><a class="reference internal" href="#databases" id="id33">数据库</a></p>
|
||||
<ul>
|
||||
<li><p><a class="reference internal" href="#are-there-any-interfaces-to-database-packages-in-python" id="id34">Python 中有数据库包的接口吗?</a></p></li>
|
||||
<li><p><a class="reference internal" href="#how-do-you-implement-persistent-objects-in-python" id="id35">在 Python 中如何实现持久化对象?</a></p></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li><p><a class="reference internal" href="#mathematics-and-numerics" id="id36">数学和数字</a></p>
|
||||
<ul>
|
||||
<li><p><a class="reference internal" href="#how-do-i-generate-random-numbers-in-python" id="id37">Python 中怎样生成随机数?</a></p></li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
<section id="general-library-questions">
|
||||
<h2><a class="toc-backref" href="#id3">通用的代码库问题</a><a class="headerlink" href="#general-library-questions" title="永久链接至标题">¶</a></h2>
|
||||
<section id="how-do-i-find-a-module-or-application-to-perform-task-x">
|
||||
<h3><a class="toc-backref" href="#id4">如何找到可以用来做 XXX 的模块或应用?</a><a class="headerlink" href="#how-do-i-find-a-module-or-application-to-perform-task-x" title="永久链接至标题">¶</a></h3>
|
||||
<p>在 <a class="reference internal" href="../library/index.html#library-index"><span class="std std-ref">代码库参考</span></a> 中查找是否有适合的标准库模块。(如果你已经了解标准库的内容,可以跳过这一步)</p>
|
||||
<p>对于第三方软件包,请搜索 <a class="reference external" href="https://pypi.org">Python Package Index</a> 或是 <a class="reference external" href="https://www.google.com">Google</a> 等其他搜索引擎。用“Python”加上一两个你需要的关键字通常会找到有用的东西。</p>
|
||||
</section>
|
||||
<section id="where-is-the-math-py-socket-py-regex-py-etc-source-file">
|
||||
<h3><a class="toc-backref" href="#id5">math.py(socket.py,regex.py 等)的源文件在哪?</a><a class="headerlink" href="#where-is-the-math-py-socket-py-regex-py-etc-source-file" title="永久链接至标题">¶</a></h3>
|
||||
<p>如果找不到模块的源文件,可能它是一个内建的模块,或是使用 C,C++ 或其他编译型语言实现的动态加载模块。这种情况下可能是没有源码文件的,类似 <code class="file docutils literal notranslate"><span class="pre">mathmodule.c</span></code> 这样的文件会存放在 C 代码目录中(但不在 Python 目录中)。</p>
|
||||
<p>Python 中(至少)有三类模块:</p>
|
||||
<ol class="arabic">
|
||||
<li><p>使用 Python 编写的模块(.py);</p></li>
|
||||
<li><p>使用 C 编写的动态加载模块(.dll,.pyd,.so,.sl 等);</p></li>
|
||||
<li><p>使用 C 编写并链接到解释器的模块,要获取此列表,输入:</p>
|
||||
<div class="highlight-python3 notranslate"><div class="highlight"><pre><span></span><span class="kn">import</span> <span class="nn">sys</span>
|
||||
<span class="nb">print</span><span class="p">(</span><span class="n">sys</span><span class="o">.</span><span class="n">builtin_module_names</span><span class="p">)</span>
|
||||
</pre></div>
|
||||
</div>
|
||||
</li>
|
||||
</ol>
|
||||
</section>
|
||||
<section id="how-do-i-make-a-python-script-executable-on-unix">
|
||||
<h3><a class="toc-backref" href="#id6">在 Unix 中怎样让 Python 脚本可执行?</a><a class="headerlink" href="#how-do-i-make-a-python-script-executable-on-unix" title="永久链接至标题">¶</a></h3>
|
||||
<p>你需要做两件事:文件必须是可执行的,并且第一行需要以 <code class="docutils literal notranslate"><span class="pre">#!</span></code> 开头,后面跟上 Python 解释器的路径。</p>
|
||||
<p>第一点可以用执行 <code class="docutils literal notranslate"><span class="pre">chmod</span> <span class="pre">+x</span> <span class="pre">scriptfile</span></code> 或是 <code class="docutils literal notranslate"><span class="pre">chmod</span> <span class="pre">755</span> <span class="pre">scriptfile</span></code> 做到。</p>
|
||||
<p>第二点有很多种做法,最直接的方式是:</p>
|
||||
<div class="highlight-python3 notranslate"><div class="highlight"><pre><span></span><span class="ch">#!/usr/local/bin/python</span>
|
||||
</pre></div>
|
||||
</div>
|
||||
<p>在文件第一行,使用你所在平台上的 Python 解释器的路径。</p>
|
||||
<p>如果你希望脚本不依赖 Python 解释器的具体路径,你也可以使用 <strong class="program">env</strong> 程序。假设你的 Python 解释器所在目录已经添加到了 <span class="target" id="index-4"></span><code class="xref std std-envvar docutils literal notranslate"><span class="pre">PATH</span></code> 环境变量中,几乎所有的类 Unix 系统都支持下面的写法:</p>
|
||||
<div class="highlight-python3 notranslate"><div class="highlight"><pre><span></span><span class="ch">#!/usr/bin/env python</span>
|
||||
</pre></div>
|
||||
</div>
|
||||
<p><em>不要</em> 在 CGI 脚本中这样做。CGI 脚本的 <span class="target" id="index-5"></span><code class="xref std std-envvar docutils literal notranslate"><span class="pre">PATH</span></code> 环境变量通常会非常精简,所以你必须使用解释器的完整绝对路径。</p>
|
||||
<p>有时候,用户的环境变量如果太长,可能会导致 <strong class="program">/usr/bin/env</strong> 执行失败;又或者甚至根本就不存在 env 程序。在这种情况下,你可以尝试使用下面的 hack 方法(来自 Alex Rezinsky):</p>
|
||||
<div class="highlight-sh notranslate"><div class="highlight"><pre><span></span><span class="ch">#! /bin/sh</span>
|
||||
<span class="s2">""":"</span>
|
||||
<span class="nb">exec</span><span class="w"> </span>python<span class="w"> </span><span class="nv">$0</span><span class="w"> </span><span class="si">${</span><span class="nv">1</span><span class="p">+</span><span class="s2">"</span><span class="nv">$@</span><span class="s2">"</span><span class="si">}</span>
|
||||
<span class="s2">"""</span>
|
||||
</pre></div>
|
||||
</div>
|
||||
<p>这样做有一个小小的缺点,它会定义脚本的 __doc__ 字符串。不过可以这样修复:</p>
|
||||
<div class="highlight-python3 notranslate"><div class="highlight"><pre><span></span><span class="vm">__doc__</span> <span class="o">=</span> <span class="s2">"""...Whatever..."""</span>
|
||||
</pre></div>
|
||||
</div>
|
||||
</section>
|
||||
<section id="is-there-a-curses-termcap-package-for-python">
|
||||
<h3><a class="toc-backref" href="#id7">Python 中有 curses/termcap 包吗?</a><a class="headerlink" href="#is-there-a-curses-termcap-package-for-python" title="永久链接至标题">¶</a></h3>
|
||||
<p>对于类 Unix 系统:标准 Python 源码发行版会在 <a class="reference external" href="https://github.com/python/cpython/tree/3.8/Modules">Modules</a> 子目录中附带 curses 模块,但默认并不会编译。(注意:在 Windows 平台下不可用 —— Windows 中没有 curses 模块。)</p>
|
||||
<p><a class="reference internal" href="../library/curses.html#module-curses" title="curses: An interface to the curses library, providing portable terminal handling. (Unix)"><code class="xref py py-mod docutils literal notranslate"><span class="pre">curses</span></code></a> 模块支持基本的 curses 特性,同时也支持 ncurses 和 SYSV curses 中的很多额外功能,比如颜色、不同的字符集支持、填充和鼠标支持。这意味着这个模块不兼容只有 BSD curses 模块的操作系统,但是目前仍在维护的系统应该都不会存在这种情况。</p>
|
||||
<p>对于 Windows 平台:使用 <a class="reference external" href="http://effbot.org/zone/console-index.htm">consolelib 模块</a>.</p>
|
||||
</section>
|
||||
<section id="is-there-an-equivalent-to-c-s-onexit-in-python">
|
||||
<h3><a class="toc-backref" href="#id8">Python 中存在类似 C 的 onexit() 函数的东西吗?</a><a class="headerlink" href="#is-there-an-equivalent-to-c-s-onexit-in-python" title="永久链接至标题">¶</a></h3>
|
||||
<p><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> 模块提供了一个与 C 的 <code class="xref c c-func docutils literal notranslate"><span class="pre">onexit()</span></code> 函数类似的注册函数。</p>
|
||||
</section>
|
||||
<section id="why-don-t-my-signal-handlers-work">
|
||||
<h3><a class="toc-backref" href="#id9">为什么我的信号处理函数不能工作?</a><a class="headerlink" href="#why-don-t-my-signal-handlers-work" title="永久链接至标题">¶</a></h3>
|
||||
<p>最常见的问题是信号处理函数没有正确定义参数列表。它会被这样调用:</p>
|
||||
<div class="highlight-python3 notranslate"><div class="highlight"><pre><span></span><span class="n">handler</span><span class="p">(</span><span class="n">signum</span><span class="p">,</span> <span class="n">frame</span><span class="p">)</span>
|
||||
</pre></div>
|
||||
</div>
|
||||
<p>因此函数应该定义两个参数:</p>
|
||||
<div class="highlight-python3 notranslate"><div class="highlight"><pre><span></span><span class="k">def</span> <span class="nf">handler</span><span class="p">(</span><span class="n">signum</span><span class="p">,</span> <span class="n">frame</span><span class="p">):</span>
|
||||
<span class="o">...</span>
|
||||
</pre></div>
|
||||
</div>
|
||||
</section>
|
||||
</section>
|
||||
<section id="common-tasks">
|
||||
<h2><a class="toc-backref" href="#id10">通用任务</a><a class="headerlink" href="#common-tasks" title="永久链接至标题">¶</a></h2>
|
||||
<section id="how-do-i-test-a-python-program-or-component">
|
||||
<h3><a class="toc-backref" href="#id11">怎样测试 Python 程序或组件?</a><a class="headerlink" href="#how-do-i-test-a-python-program-or-component" title="永久链接至标题">¶</a></h3>
|
||||
<p>Python 带有两个测试框架。<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> 模块从模块的 docstring 中寻找示例并执行,对比输出是否与 docstring 中给出的是否一致。</p>
|
||||
<p><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> 模块是一个模仿 Java 和 Smalltalk 测试框架的更棒的测试框架。</p>
|
||||
<p>为了使测试更容易,你应该在程序中使用良好的模块化设计。程序中的绝大多数功能都应该用函数或类方法封装 —— 有时这样做会有额外惊喜,程序会运行得更快(因为局部变量比全局变量访问要快)。除此之外,程序应该避免依赖可变的局部变量,这会使得测试困难许多。</p>
|
||||
<p>程序的“全局主逻辑”应该尽量简单:</p>
|
||||
<div class="highlight-python3 notranslate"><div class="highlight"><pre><span></span><span class="k">if</span> <span class="vm">__name__</span> <span class="o">==</span> <span class="s2">"__main__"</span><span class="p">:</span>
|
||||
<span class="n">main_logic</span><span class="p">()</span>
|
||||
</pre></div>
|
||||
</div>
|
||||
<p>并放置在程序主模块的最后面。</p>
|
||||
<p>一旦你的程序已经用函数和类完善地组织起来,你就应该编写测试函数来测试其行为。可以使用自动执行一系列测试函数的测试集与每个模块进行关联。听起来似乎需要大量的工作,但是因为 Python 非常简洁和灵活,所以实际上会相当简单。在编写“生产代码”的同时别忘了也要编写测试函数,你会发现编程会变得更愉快、更有趣,因为这样会使得发现 bug 和设计缺陷更加容易。</p>
|
||||
<p>程序主模块之外的其他“辅助模块”中可以增加自测试的入口。</p>
|
||||
<div class="highlight-python3 notranslate"><div class="highlight"><pre><span></span><span class="k">if</span> <span class="vm">__name__</span> <span class="o">==</span> <span class="s2">"__main__"</span><span class="p">:</span>
|
||||
<span class="n">self_test</span><span class="p">()</span>
|
||||
</pre></div>
|
||||
</div>
|
||||
<p>通过使用 Python 实现的“假”接口,即使是需要与复杂的外部接口交互的程序也可以在外部接口不可用时进行测试。</p>
|
||||
</section>
|
||||
<section id="how-do-i-create-documentation-from-doc-strings">
|
||||
<h3><a class="toc-backref" href="#id12">怎样用 docstring 创建文档?</a><a class="headerlink" href="#how-do-i-create-documentation-from-doc-strings" title="永久链接至标题">¶</a></h3>
|
||||
<p><a class="reference internal" href="../library/pydoc.html#module-pydoc" title="pydoc: Documentation generator and online help system."><code class="xref py py-mod docutils literal notranslate"><span class="pre">pydoc</span></code></a> 模块可以用 Python 源码中的 docstring 创建 HTML 文件。也可以使用 <a class="reference external" href="http://epydoc.sourceforge.net/">epydoc</a> 来只通过 docstring 创建 API 文档。<a class="reference external" href="http://sphinx-doc.org">Sphinx</a> 也可以引入 docstring 的内容。</p>
|
||||
</section>
|
||||
<section id="how-do-i-get-a-single-keypress-at-a-time">
|
||||
<h3><a class="toc-backref" href="#id13">怎样一次只获取一个按键?</a><a class="headerlink" href="#how-do-i-get-a-single-keypress-at-a-time" title="永久链接至标题">¶</a></h3>
|
||||
<p>在类 Unix 系统中有多种方案。最直接的方法是使用 curses,但是 curses 模块太大了,难以学习。</p>
|
||||
</section>
|
||||
</section>
|
||||
<section id="threads">
|
||||
<h2><a class="toc-backref" href="#id14">线程相关</a><a class="headerlink" href="#threads" title="永久链接至标题">¶</a></h2>
|
||||
<section id="how-do-i-program-using-threads">
|
||||
<h3><a class="toc-backref" href="#id15">程序中怎样使用线程?</a><a class="headerlink" href="#how-do-i-program-using-threads" title="永久链接至标题">¶</a></h3>
|
||||
<p>一定要使用 <a class="reference internal" href="../library/threading.html#module-threading" title="threading: Thread-based parallelism."><code class="xref py py-mod docutils literal notranslate"><span class="pre">threading</span></code></a> 模块,不要使用 <a class="reference internal" href="../library/_thread.html#module-_thread" title="_thread: Low-level threading API."><code class="xref py py-mod docutils literal notranslate"><span class="pre">_thread</span></code></a> 模块。<a class="reference internal" href="../library/threading.html#module-threading" title="threading: Thread-based parallelism."><code class="xref py py-mod docutils literal notranslate"><span class="pre">threading</span></code></a> 模块对 <a class="reference internal" href="../library/_thread.html#module-_thread" title="_thread: Low-level threading API."><code class="xref py py-mod docutils literal notranslate"><span class="pre">_thread</span></code></a> 模块提供的底层线程原语做了更易用的抽象。</p>
|
||||
<p>Aahz 的非常实用的 threading 教程中有一些幻灯片;可以参阅 <a class="reference external" href="http://www.pythoncraft.com/OSCON2001/">http://www.pythoncraft.com/OSCON2001/</a> 。</p>
|
||||
</section>
|
||||
<section id="none-of-my-threads-seem-to-run-why">
|
||||
<h3><a class="toc-backref" href="#id16">我的线程都没有运行,为什么?</a><a class="headerlink" href="#none-of-my-threads-seem-to-run-why" title="永久链接至标题">¶</a></h3>
|
||||
<p>一旦主线程退出,所有的子线程都会被杀掉。你的主线程运行得太快了,子线程还没来得及工作。</p>
|
||||
<p>简单的解决方法是在程序中加一个时间足够长的 sleep,让子线程能够完成运行。</p>
|
||||
<div class="highlight-python3 notranslate"><div class="highlight"><pre><span></span><span class="kn">import</span> <span class="nn">threading</span><span class="o">,</span> <span class="nn">time</span>
|
||||
|
||||
<span class="k">def</span> <span class="nf">thread_task</span><span class="p">(</span><span class="n">name</span><span class="p">,</span> <span class="n">n</span><span class="p">):</span>
|
||||
<span class="k">for</span> <span class="n">i</span> <span class="ow">in</span> <span class="nb">range</span><span class="p">(</span><span class="n">n</span><span class="p">):</span>
|
||||
<span class="nb">print</span><span class="p">(</span><span class="n">name</span><span class="p">,</span> <span class="n">i</span><span class="p">)</span>
|
||||
|
||||
<span class="k">for</span> <span class="n">i</span> <span class="ow">in</span> <span class="nb">range</span><span class="p">(</span><span class="mi">10</span><span class="p">):</span>
|
||||
<span class="n">T</span> <span class="o">=</span> <span class="n">threading</span><span class="o">.</span><span class="n">Thread</span><span class="p">(</span><span class="n">target</span><span class="o">=</span><span class="n">thread_task</span><span class="p">,</span> <span class="n">args</span><span class="o">=</span><span class="p">(</span><span class="nb">str</span><span class="p">(</span><span class="n">i</span><span class="p">),</span> <span class="n">i</span><span class="p">))</span>
|
||||
<span class="n">T</span><span class="o">.</span><span class="n">start</span><span class="p">()</span>
|
||||
|
||||
<span class="n">time</span><span class="o">.</span><span class="n">sleep</span><span class="p">(</span><span class="mi">10</span><span class="p">)</span> <span class="c1"># <---------------------------!</span>
|
||||
</pre></div>
|
||||
</div>
|
||||
<p>但目前(在许多平台上)线程不是并行运行的,而是按顺序依次执行!原因是系统线程调度器在前一个线程阻塞之前不会启动新线程。</p>
|
||||
<p>简单的解决方法是在运行函数的开始处加一个时间很短的 sleep。</p>
|
||||
<div class="highlight-python3 notranslate"><div class="highlight"><pre><span></span><span class="k">def</span> <span class="nf">thread_task</span><span class="p">(</span><span class="n">name</span><span class="p">,</span> <span class="n">n</span><span class="p">):</span>
|
||||
<span class="n">time</span><span class="o">.</span><span class="n">sleep</span><span class="p">(</span><span class="mf">0.001</span><span class="p">)</span> <span class="c1"># <--------------------!</span>
|
||||
<span class="k">for</span> <span class="n">i</span> <span class="ow">in</span> <span class="nb">range</span><span class="p">(</span><span class="n">n</span><span class="p">):</span>
|
||||
<span class="nb">print</span><span class="p">(</span><span class="n">name</span><span class="p">,</span> <span class="n">i</span><span class="p">)</span>
|
||||
|
||||
<span class="k">for</span> <span class="n">i</span> <span class="ow">in</span> <span class="nb">range</span><span class="p">(</span><span class="mi">10</span><span class="p">):</span>
|
||||
<span class="n">T</span> <span class="o">=</span> <span class="n">threading</span><span class="o">.</span><span class="n">Thread</span><span class="p">(</span><span class="n">target</span><span class="o">=</span><span class="n">thread_task</span><span class="p">,</span> <span class="n">args</span><span class="o">=</span><span class="p">(</span><span class="nb">str</span><span class="p">(</span><span class="n">i</span><span class="p">),</span> <span class="n">i</span><span class="p">))</span>
|
||||
<span class="n">T</span><span class="o">.</span><span class="n">start</span><span class="p">()</span>
|
||||
|
||||
<span class="n">time</span><span class="o">.</span><span class="n">sleep</span><span class="p">(</span><span class="mi">10</span><span class="p">)</span>
|
||||
</pre></div>
|
||||
</div>
|
||||
<p>比起用 <a class="reference internal" href="../library/time.html#time.sleep" title="time.sleep"><code class="xref py py-func docutils literal notranslate"><span class="pre">time.sleep()</span></code></a> 猜一个合适的等待时间,使用信号量机制会更好些。有一个办法是使用 <a class="reference internal" href="../library/queue.html#module-queue" title="queue: A synchronized queue class."><code class="xref py py-mod docutils literal notranslate"><span class="pre">queue</span></code></a> 模块创建一个 queue 对象,让每一个线程在运行结束时 append 一个令牌到 queue 对象中,主线程中从 queue 对象中读取与线程数量一致的令牌数量即可。</p>
|
||||
</section>
|
||||
<section id="how-do-i-parcel-out-work-among-a-bunch-of-worker-threads">
|
||||
<h3><a class="toc-backref" href="#id17">如何将任务分配给多个工作线程?</a><a class="headerlink" href="#how-do-i-parcel-out-work-among-a-bunch-of-worker-threads" title="永久链接至标题">¶</a></h3>
|
||||
<p>最简单的方法是使用新的 <a class="reference internal" href="../library/concurrent.futures.html#module-concurrent.futures" title="concurrent.futures: Execute computations concurrently using threads or processes."><code class="xref py py-mod docutils literal notranslate"><span class="pre">concurrent.futures</span></code></a> 模块,尤其是其中的 <a class="reference internal" href="../library/concurrent.futures.html#concurrent.futures.ThreadPoolExecutor" title="concurrent.futures.ThreadPoolExecutor"><code class="xref py py-mod docutils literal notranslate"><span class="pre">ThreadPoolExecutor</span></code></a> 类。</p>
|
||||
<p>或者,如果你想更好地控制分发算法,你也可以自己写逻辑实现。使用 <a class="reference internal" href="../library/queue.html#module-queue" title="queue: A synchronized queue class."><code class="xref py py-mod docutils literal notranslate"><span class="pre">queue</span></code></a> 模块来创建任务列表队列。<a class="reference internal" href="../library/queue.html#queue.Queue" title="queue.Queue"><code class="xref py py-class docutils literal notranslate"><span class="pre">Queue</span></code></a> 类维护一个了一个存有对象的列表,提供了 <code class="docutils literal notranslate"><span class="pre">.put(obj)</span></code> 方法添加元素,并且可以用 <code class="docutils literal notranslate"><span class="pre">.get()</span></code> 方法获取元素。这个类会使用必要的加锁操作,以此确保每个任务只会执行一次。</p>
|
||||
<p>这是一个简单的例子:</p>
|
||||
<div class="highlight-python3 notranslate"><div class="highlight"><pre><span></span><span class="kn">import</span> <span class="nn">threading</span><span class="o">,</span> <span class="nn">queue</span><span class="o">,</span> <span class="nn">time</span>
|
||||
|
||||
<span class="c1"># The worker thread gets jobs off the queue. When the queue is empty, it</span>
|
||||
<span class="c1"># assumes there will be no more work and exits.</span>
|
||||
<span class="c1"># (Realistically workers will run until terminated.)</span>
|
||||
<span class="k">def</span> <span class="nf">worker</span><span class="p">():</span>
|
||||
<span class="nb">print</span><span class="p">(</span><span class="s1">'Running worker'</span><span class="p">)</span>
|
||||
<span class="n">time</span><span class="o">.</span><span class="n">sleep</span><span class="p">(</span><span class="mf">0.1</span><span class="p">)</span>
|
||||
<span class="k">while</span> <span class="kc">True</span><span class="p">:</span>
|
||||
<span class="k">try</span><span class="p">:</span>
|
||||
<span class="n">arg</span> <span class="o">=</span> <span class="n">q</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="n">block</span><span class="o">=</span><span class="kc">False</span><span class="p">)</span>
|
||||
<span class="k">except</span> <span class="n">queue</span><span class="o">.</span><span class="n">Empty</span><span class="p">:</span>
|
||||
<span class="nb">print</span><span class="p">(</span><span class="s1">'Worker'</span><span class="p">,</span> <span class="n">threading</span><span class="o">.</span><span class="n">currentThread</span><span class="p">(),</span> <span class="n">end</span><span class="o">=</span><span class="s1">' '</span><span class="p">)</span>
|
||||
<span class="nb">print</span><span class="p">(</span><span class="s1">'queue empty'</span><span class="p">)</span>
|
||||
<span class="k">break</span>
|
||||
<span class="k">else</span><span class="p">:</span>
|
||||
<span class="nb">print</span><span class="p">(</span><span class="s1">'Worker'</span><span class="p">,</span> <span class="n">threading</span><span class="o">.</span><span class="n">currentThread</span><span class="p">(),</span> <span class="n">end</span><span class="o">=</span><span class="s1">' '</span><span class="p">)</span>
|
||||
<span class="nb">print</span><span class="p">(</span><span class="s1">'running with argument'</span><span class="p">,</span> <span class="n">arg</span><span class="p">)</span>
|
||||
<span class="n">time</span><span class="o">.</span><span class="n">sleep</span><span class="p">(</span><span class="mf">0.5</span><span class="p">)</span>
|
||||
|
||||
<span class="c1"># Create queue</span>
|
||||
<span class="n">q</span> <span class="o">=</span> <span class="n">queue</span><span class="o">.</span><span class="n">Queue</span><span class="p">()</span>
|
||||
|
||||
<span class="c1"># Start a pool of 5 workers</span>
|
||||
<span class="k">for</span> <span class="n">i</span> <span class="ow">in</span> <span class="nb">range</span><span class="p">(</span><span class="mi">5</span><span class="p">):</span>
|
||||
<span class="n">t</span> <span class="o">=</span> <span class="n">threading</span><span class="o">.</span><span class="n">Thread</span><span class="p">(</span><span class="n">target</span><span class="o">=</span><span class="n">worker</span><span class="p">,</span> <span class="n">name</span><span class="o">=</span><span class="s1">'worker </span><span class="si">%i</span><span class="s1">'</span> <span class="o">%</span> <span class="p">(</span><span class="n">i</span><span class="o">+</span><span class="mi">1</span><span class="p">))</span>
|
||||
<span class="n">t</span><span class="o">.</span><span class="n">start</span><span class="p">()</span>
|
||||
|
||||
<span class="c1"># Begin adding work to the queue</span>
|
||||
<span class="k">for</span> <span class="n">i</span> <span class="ow">in</span> <span class="nb">range</span><span class="p">(</span><span class="mi">50</span><span class="p">):</span>
|
||||
<span class="n">q</span><span class="o">.</span><span class="n">put</span><span class="p">(</span><span class="n">i</span><span class="p">)</span>
|
||||
|
||||
<span class="c1"># Give threads time to run</span>
|
||||
<span class="nb">print</span><span class="p">(</span><span class="s1">'Main thread sleeping'</span><span class="p">)</span>
|
||||
<span class="n">time</span><span class="o">.</span><span class="n">sleep</span><span class="p">(</span><span class="mi">5</span><span class="p">)</span>
|
||||
</pre></div>
|
||||
</div>
|
||||
<p>运行时会产生如下输出:</p>
|
||||
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>Running worker
|
||||
Running worker
|
||||
Running worker
|
||||
Running worker
|
||||
Running worker
|
||||
Main thread sleeping
|
||||
Worker <Thread(worker 1, started 130283832797456)> running with argument 0
|
||||
Worker <Thread(worker 2, started 130283824404752)> running with argument 1
|
||||
Worker <Thread(worker 3, started 130283816012048)> running with argument 2
|
||||
Worker <Thread(worker 4, started 130283807619344)> running with argument 3
|
||||
Worker <Thread(worker 5, started 130283799226640)> running with argument 4
|
||||
Worker <Thread(worker 1, started 130283832797456)> running with argument 5
|
||||
...
|
||||
</pre></div>
|
||||
</div>
|
||||
<p>查看模块的文档以获取更多信息;<a class="reference internal" href="../library/queue.html#queue.Queue" title="queue.Queue"><code class="xref py py-class docutils literal notranslate"><span class="pre">Queue</span></code></a> 类提供了多种接口。</p>
|
||||
</section>
|
||||
<section id="what-kinds-of-global-value-mutation-are-thread-safe">
|
||||
<h3><a class="toc-backref" href="#id18">怎样修改全局变量是线程安全的?</a><a class="headerlink" href="#what-kinds-of-global-value-mutation-are-thread-safe" title="永久链接至标题">¶</a></h3>
|
||||
<p>Python VM 内部会使用 <a class="reference internal" href="../glossary.html#term-global-interpreter-lock"><span class="xref std std-term">global interpreter lock</span></a> (GIL)来确保同一时间只有一个线程运行。通常 Python 只会在字节码指令之间切换线程;切换的频率可以通过设置 <a class="reference internal" href="../library/sys.html#sys.setswitchinterval" title="sys.setswitchinterval"><code class="xref py py-func docutils literal notranslate"><span class="pre">sys.setswitchinterval()</span></code></a> 指定。从 Python 程序的角度来看,每一条字节码指令以及每一条指令对应的 C 代码实现都是原子的。</p>
|
||||
<p>理论上说,具体的结果要看具体的 PVM 字节码实现对指令的解释。而实际上,对内建类型(int,list,dict 等)的共享变量的“类原子”操作都是原子的。</p>
|
||||
<p>举例来说,下面的操作是原子的(L、L1、L2 是列表,D、D1、D2 是字典,x、y 是对象,i,j 是 int 变量):</p>
|
||||
<div class="highlight-python3 notranslate"><div class="highlight"><pre><span></span><span class="n">L</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">x</span><span class="p">)</span>
|
||||
<span class="n">L1</span><span class="o">.</span><span class="n">extend</span><span class="p">(</span><span class="n">L2</span><span class="p">)</span>
|
||||
<span class="n">x</span> <span class="o">=</span> <span class="n">L</span><span class="p">[</span><span class="n">i</span><span class="p">]</span>
|
||||
<span class="n">x</span> <span class="o">=</span> <span class="n">L</span><span class="o">.</span><span class="n">pop</span><span class="p">()</span>
|
||||
<span class="n">L1</span><span class="p">[</span><span class="n">i</span><span class="p">:</span><span class="n">j</span><span class="p">]</span> <span class="o">=</span> <span class="n">L2</span>
|
||||
<span class="n">L</span><span class="o">.</span><span class="n">sort</span><span class="p">()</span>
|
||||
<span class="n">x</span> <span class="o">=</span> <span class="n">y</span>
|
||||
<span class="n">x</span><span class="o">.</span><span class="n">field</span> <span class="o">=</span> <span class="n">y</span>
|
||||
<span class="n">D</span><span class="p">[</span><span class="n">x</span><span class="p">]</span> <span class="o">=</span> <span class="n">y</span>
|
||||
<span class="n">D1</span><span class="o">.</span><span class="n">update</span><span class="p">(</span><span class="n">D2</span><span class="p">)</span>
|
||||
<span class="n">D</span><span class="o">.</span><span class="n">keys</span><span class="p">()</span>
|
||||
</pre></div>
|
||||
</div>
|
||||
<p>这些不是原子的:</p>
|
||||
<div class="highlight-python3 notranslate"><div class="highlight"><pre><span></span><span class="n">i</span> <span class="o">=</span> <span class="n">i</span><span class="o">+</span><span class="mi">1</span>
|
||||
<span class="n">L</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">L</span><span class="p">[</span><span class="o">-</span><span class="mi">1</span><span class="p">])</span>
|
||||
<span class="n">L</span><span class="p">[</span><span class="n">i</span><span class="p">]</span> <span class="o">=</span> <span class="n">L</span><span class="p">[</span><span class="n">j</span><span class="p">]</span>
|
||||
<span class="n">D</span><span class="p">[</span><span class="n">x</span><span class="p">]</span> <span class="o">=</span> <span class="n">D</span><span class="p">[</span><span class="n">x</span><span class="p">]</span> <span class="o">+</span> <span class="mi">1</span>
|
||||
</pre></div>
|
||||
</div>
|
||||
<p>覆盖其他对象的操作会在其他对象的引用计数变成 0 时触发其 <a class="reference internal" href="../reference/datamodel.html#object.__del__" title="object.__del__"><code class="xref py py-meth docutils literal notranslate"><span class="pre">__del__()</span></code></a> 方法,这可能会产生一些影响。对字典和列表进行大量操作时尤其如此。如果有疑问的话,使用互斥锁!</p>
|
||||
</section>
|
||||
<section id="can-t-we-get-rid-of-the-global-interpreter-lock">
|
||||
<h3><a class="toc-backref" href="#id19">不能删除全局解释器锁吗?</a><a class="headerlink" href="#can-t-we-get-rid-of-the-global-interpreter-lock" title="永久链接至标题">¶</a></h3>
|
||||
<p><a class="reference internal" href="../glossary.html#term-global-interpreter-lock"><span class="xref std std-term">global interpreter lock</span></a> (GIL)通常被视为 Python 在高端多核服务器上开发时的阻力,因为(几乎)所有 Python 代码只有在获取到 GIL 时才能运行,所以多线程的 Python 程序只能有效地使用一个 CPU。</p>
|
||||
<p>在 Python 1.5 时代,Greg Stein 开发了一个完整的补丁包(“free threadings” 补丁),移除了 GIL,并用粒度更合适的锁来代替。Adam Olsen 最近也在他的 <a class="reference external" href="https://code.google.com/archive/p/python-safethread">python-safethread</a> 项目里做了类似的实验。不幸的是,由于为了移除 GIL 而使用了大量细粒度的锁,这两个实验在单线程测试中的性能都有明显的下降(至少慢 30%)。</p>
|
||||
<p>但这并意味着你不能在多核机器上很好地使用 Python!你只需将任务划分为多*进程*,而不是多*线程*。新的 <a class="reference internal" href="../library/concurrent.futures.html#module-concurrent.futures" title="concurrent.futures: Execute computations concurrently using threads or processes."><code class="xref py py-mod docutils literal notranslate"><span class="pre">concurrent.futures</span></code></a> 模块中的 <a class="reference internal" href="../library/concurrent.futures.html#concurrent.futures.ProcessPoolExecutor" title="concurrent.futures.ProcessPoolExecutor"><code class="xref py py-class docutils literal notranslate"><span class="pre">ProcessPoolExecutor</span></code></a> 类提供了一个简单的方法;如果你想对任务分发做更多控制,可以使用 <a class="reference internal" href="../library/multiprocessing.html#module-multiprocessing" title="multiprocessing: Process-based parallelism."><code class="xref py py-mod docutils literal notranslate"><span class="pre">multiprocessing</span></code></a> 模块提供的底层 API。</p>
|
||||
<p>恰当地使用 C 拓展也很有用;使用 C 拓展处理耗时较久的任务时,拓展可以在线程执行 C 代码时释放 GIL,让其他线程执行。<a class="reference internal" href="../library/zlib.html#module-zlib" title="zlib: Low-level interface to compression and decompression routines compatible with gzip."><code class="xref py py-mod docutils literal notranslate"><span class="pre">zlib</span></code></a> 和 <a class="reference internal" href="../library/hashlib.html#module-hashlib" title="hashlib: Secure hash and message digest algorithms."><code class="xref py py-mod docutils literal notranslate"><span class="pre">hashlib</span></code></a> 等标准库模块已经这样做了。</p>
|
||||
<p>也有建议说 GIL 应该是解释器状态锁,而不是完全的全局锁;解释器不应该共享对象。不幸的是,这也不可能发生。由于目前许多对象的实现都有全局的状态,因此这是一个艰巨的工作。举例来说,小整型数和短字符串会缓存起来,这些缓存将不得不移动到解释器状态中。其他对象类型都有自己的自由变量列表,这些自由变量列表也必须移动到解释器状态中。等等。</p>
|
||||
<p>我甚至怀疑这些工作是否可能在有限的时间内完成,因为同样的问题在第三方拓展中也会存在。第三方拓展编写的速度可比你将它们转换为把全局状态存入解释器状态中的速度快得多。</p>
|
||||
<p>最后,假设多个解释器不共享任何状态,那么这样做比每个进程一个解释器好在哪里呢?</p>
|
||||
</section>
|
||||
</section>
|
||||
<section id="input-and-output">
|
||||
<h2><a class="toc-backref" href="#id20">输入输出</a><a class="headerlink" href="#input-and-output" title="永久链接至标题">¶</a></h2>
|
||||
<section id="how-do-i-delete-a-file-and-other-file-questions">
|
||||
<h3><a class="toc-backref" href="#id21">怎样删除文件?(以及其他文件相关的问题……)</a><a class="headerlink" href="#how-do-i-delete-a-file-and-other-file-questions" title="永久链接至标题">¶</a></h3>
|
||||
<p>使用 <code class="docutils literal notranslate"><span class="pre">os.remove(filename)</span></code> 或 <code class="docutils literal notranslate"><span class="pre">os.unlink(filename)</span></code>。查看 <a class="reference internal" href="../library/os.html#module-os" title="os: Miscellaneous operating system interfaces."><code class="xref py py-mod docutils literal notranslate"><span class="pre">os</span></code></a> 模块以获取更多文档。这两个函数是一样的,<a class="reference internal" href="../library/os.html#os.unlink" title="os.unlink"><code class="xref py py-func docutils literal notranslate"><span class="pre">unlink()</span></code></a> 是这个函数在 Unix 系统调用中的名字。</p>
|
||||
<p>如果要删除目录,应该使用 <a class="reference internal" href="../library/os.html#os.rmdir" title="os.rmdir"><code class="xref py py-func docutils literal notranslate"><span class="pre">os.rmdir()</span></code></a>;使用 <a class="reference internal" href="../library/os.html#os.mkdir" title="os.mkdir"><code class="xref py py-func docutils literal notranslate"><span class="pre">os.mkdir()</span></code></a> 创建目录。<code class="docutils literal notranslate"><span class="pre">os.makedirs(path)</span></code> 会创建 <code class="docutils literal notranslate"><span class="pre">path</span></code> 中任何不存在的目录。<code class="docutils literal notranslate"><span class="pre">os.removedirs(path)</span></code> 则会删除其中的目录,只要它们都是空的;如果你想删除整个目录以及其中的内容,可以使用 <a class="reference internal" href="../library/shutil.html#shutil.rmtree" title="shutil.rmtree"><code class="xref py py-func docutils literal notranslate"><span class="pre">shutil.rmtree()</span></code></a>。</p>
|
||||
<p>重命名文件可以使用 <code class="docutils literal notranslate"><span class="pre">os.rename(old_path,</span> <span class="pre">new_path)</span></code>。</p>
|
||||
<p>如果需要截断文件,使用 <code class="docutils literal notranslate"><span class="pre">f</span> <span class="pre">=</span> <span class="pre">open(filename,</span> <span class="pre">"rb+")</span></code> 打开文件,然后使用 <code class="docutils literal notranslate"><span class="pre">f.truncate(offset)</span></code>;offset 默认是当前的搜索位置。也可以对使用 <a class="reference internal" href="../library/os.html#os.open" title="os.open"><code class="xref py py-func docutils literal notranslate"><span class="pre">os.open()</span></code></a> 打开的文件使用 <code class="docutils literal notranslate"><span class="pre">os.ftruncate(fd,</span> <span class="pre">offset)</span></code>,其中 <em>fd</em> 是文件描述符(一个小的整型数)。</p>
|
||||
<p><a class="reference internal" href="../library/shutil.html#module-shutil" title="shutil: High-level file operations, including copying."><code class="xref py py-mod docutils literal notranslate"><span class="pre">shutil</span></code></a> 模块也包含了一些处理文件的函数,包括 <a class="reference internal" href="../library/shutil.html#shutil.copyfile" title="shutil.copyfile"><code class="xref py py-func docutils literal notranslate"><span class="pre">copyfile()</span></code></a>,<a class="reference internal" href="../library/shutil.html#shutil.copytree" title="shutil.copytree"><code class="xref py py-func docutils literal notranslate"><span class="pre">copytree()</span></code></a> 和 <a class="reference internal" href="../library/shutil.html#shutil.rmtree" title="shutil.rmtree"><code class="xref py py-func docutils literal notranslate"><span class="pre">rmtree()</span></code></a>。</p>
|
||||
</section>
|
||||
<section id="how-do-i-copy-a-file">
|
||||
<h3><a class="toc-backref" href="#id22">怎样复制文件?</a><a class="headerlink" href="#how-do-i-copy-a-file" title="永久链接至标题">¶</a></h3>
|
||||
<p><a class="reference internal" href="../library/shutil.html#module-shutil" title="shutil: High-level file operations, including copying."><code class="xref py py-mod docutils literal notranslate"><span class="pre">shutil</span></code></a> 模块有一个 <a class="reference internal" href="../library/shutil.html#shutil.copyfile" title="shutil.copyfile"><code class="xref py py-func docutils literal notranslate"><span class="pre">copyfile()</span></code></a> 函数。注意在 MacOS 9 中不会复制 resource fork 和 Finder info。</p>
|
||||
</section>
|
||||
<section id="how-do-i-read-or-write-binary-data">
|
||||
<h3><a class="toc-backref" href="#id23">怎样读取(或写入)二进制数据?</a><a class="headerlink" href="#how-do-i-read-or-write-binary-data" title="永久链接至标题">¶</a></h3>
|
||||
<p>要读写复杂的二进制数据格式,最好使用 <a class="reference internal" href="../library/struct.html#module-struct" title="struct: Interpret bytes as packed binary data."><code class="xref py py-mod docutils literal notranslate"><span class="pre">struct</span></code></a> 模块。该模块可以读取包含二进制数据(通常是数字)的字符串并转换为 Python 对象,反之亦然。</p>
|
||||
<p>举例来说,下面的代码会从文件中以大端序格式读取一个 2 字节的整型和一个 4 字节的整型:</p>
|
||||
<div class="highlight-python3 notranslate"><div class="highlight"><pre><span></span><span class="kn">import</span> <span class="nn">struct</span>
|
||||
|
||||
<span class="k">with</span> <span class="nb">open</span><span class="p">(</span><span class="n">filename</span><span class="p">,</span> <span class="s2">"rb"</span><span class="p">)</span> <span class="k">as</span> <span class="n">f</span><span class="p">:</span>
|
||||
<span class="n">s</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">8</span><span class="p">)</span>
|
||||
<span class="n">x</span><span class="p">,</span> <span class="n">y</span><span class="p">,</span> <span class="n">z</span> <span class="o">=</span> <span class="n">struct</span><span class="o">.</span><span class="n">unpack</span><span class="p">(</span><span class="s2">">hhl"</span><span class="p">,</span> <span class="n">s</span><span class="p">)</span>
|
||||
</pre></div>
|
||||
</div>
|
||||
<p>格式字符串中的 ‘>’ 强制以大端序读取数据;字母 ‘h’ 从字符串中读取一个“短整型”(2 字节),字母 ‘l’ 读取一个“长整型”(4 字节)。</p>
|
||||
<p>对于更常规的数据(例如整型或浮点类型的列表),你也可以使用 <a class="reference internal" href="../library/array.html#module-array" title="array: Space efficient arrays of uniformly typed numeric values."><code class="xref py py-mod docutils literal notranslate"><span class="pre">array</span></code></a> 模块。</p>
|
||||
<div class="admonition note">
|
||||
<p class="admonition-title">注解</p>
|
||||
<p>要读写二进制数据的话,需要强制以二进制模式打开文件(这里为 <a class="reference internal" href="../library/functions.html#open" title="open"><code class="xref py py-func docutils literal notranslate"><span class="pre">open()</span></code></a> 函数传入 <code class="docutils literal notranslate"><span class="pre">"rb"</span></code>)。如果(默认)传入 <code class="docutils literal notranslate"><span class="pre">"r"</span></code> 的话,文件会以文本模式打开,<code class="docutils literal notranslate"><span class="pre">f.read()</span></code> 会返回 <a class="reference internal" href="../library/stdtypes.html#str" title="str"><code class="xref py py-class docutils literal notranslate"><span class="pre">str</span></code></a> 对象,而不是 <a class="reference internal" href="../library/stdtypes.html#bytes" title="bytes"><code class="xref py py-class docutils literal notranslate"><span class="pre">bytes</span></code></a> 对象。</p>
|
||||
</div>
|
||||
</section>
|
||||
<section id="i-can-t-seem-to-use-os-read-on-a-pipe-created-with-os-popen-why">
|
||||
<h3><a class="toc-backref" href="#id24">似乎 os.popen() 创建的管道不能使用 os.read(),这是为什么?</a><a class="headerlink" href="#i-can-t-seem-to-use-os-read-on-a-pipe-created-with-os-popen-why" title="永久链接至标题">¶</a></h3>
|
||||
<p><a class="reference internal" href="../library/os.html#os.read" title="os.read"><code class="xref py py-func docutils literal notranslate"><span class="pre">os.read()</span></code></a> 是一个底层函数,它接收的是文件描述符 —— 用小整型数表示的打开的文件。<a class="reference internal" href="../library/os.html#os.popen" title="os.popen"><code class="xref py py-func docutils literal notranslate"><span class="pre">os.popen()</span></code></a> 创建的是一个高级文件对象,和内建的 <a class="reference internal" href="../library/functions.html#open" title="open"><code class="xref py py-func docutils literal notranslate"><span class="pre">open()</span></code></a> 方法返回的类型一样。因此,如果要从 <a class="reference internal" href="../library/os.html#os.popen" title="os.popen"><code class="xref py py-func docutils literal notranslate"><span class="pre">os.popen()</span></code></a> 创建的管道 <em>p</em> 中读取 <em>n</em> 个字节的话,你应该使用 <code class="docutils literal notranslate"><span class="pre">p.read(n)</span></code>。</p>
|
||||
</section>
|
||||
<section id="how-do-i-access-the-serial-rs232-port">
|
||||
<h3><a class="toc-backref" href="#id25">怎样访问(RS232)串口?</a><a class="headerlink" href="#how-do-i-access-the-serial-rs232-port" title="永久链接至标题">¶</a></h3>
|
||||
<p>对于 Win32,POSIX(Linux,BSD 等),Jython:</p>
|
||||
<blockquote>
|
||||
<div><p><a class="reference external" href="http://pyserial.sourceforge.net">http://pyserial.sourceforge.net</a></p>
|
||||
</div></blockquote>
|
||||
<p>对于 Unix,查看 Mitch Chapman 发布的帖子:</p>
|
||||
<blockquote>
|
||||
<div><p><a class="reference external" href="https://groups.google.com/groups?selm=34A04430.CF9@ohioee.com">https://groups.google.com/groups?selm=34A04430.CF9@ohioee.com</a></p>
|
||||
</div></blockquote>
|
||||
</section>
|
||||
<section id="why-doesn-t-closing-sys-stdout-stdin-stderr-really-close-it">
|
||||
<h3><a class="toc-backref" href="#id26">为什么关闭 sys.stdout(stdin,stderr)并不会真正关掉它?</a><a class="headerlink" href="#why-doesn-t-closing-sys-stdout-stdin-stderr-really-close-it" title="永久链接至标题">¶</a></h3>
|
||||
<p>Python <a class="reference internal" href="../glossary.html#term-file-object"><span class="xref std std-term">文件对象</span></a> 是一个对底层 C 文件描述符的高层抽象。</p>
|
||||
<p>对于在 Python 中通过内建的 <a class="reference internal" href="../library/functions.html#open" title="open"><code class="xref py py-func docutils literal notranslate"><span class="pre">open()</span></code></a> 函数创建的多数文件对象来说,<code class="docutils literal notranslate"><span class="pre">f.close()</span></code> 从 Python 的角度将其标记为已关闭,并且会关闭底层的 C 文件描述符。在 <code class="docutils literal notranslate"><span class="pre">f</span></code> 被垃圾回收的时候,析构函数中也会自动处理。</p>
|
||||
<p>但由于 stdin,stdout 和 stderr 在 C 中的特殊地位,在 Python 中也会对它们做特殊处理。运行 <code class="docutils literal notranslate"><span class="pre">sys.stdout.close()</span></code> 会将 Python 的文件对象标记为已关闭,但是*不会*关闭与之关联的文件描述符。</p>
|
||||
<p>要关闭这三者的 C 文件描述符的话,首先你应该确认确实需要关闭它(比如,这可能会影响到处理 I/O 的拓展)。如果确实需要这么做的话,使用 <a class="reference internal" href="../library/os.html#os.close" title="os.close"><code class="xref py py-func docutils literal notranslate"><span class="pre">os.close()</span></code></a>:</p>
|
||||
<div class="highlight-python3 notranslate"><div class="highlight"><pre><span></span><span class="n">os</span><span class="o">.</span><span class="n">close</span><span class="p">(</span><span class="n">stdin</span><span class="o">.</span><span class="n">fileno</span><span class="p">())</span>
|
||||
<span class="n">os</span><span class="o">.</span><span class="n">close</span><span class="p">(</span><span class="n">stdout</span><span class="o">.</span><span class="n">fileno</span><span class="p">())</span>
|
||||
<span class="n">os</span><span class="o">.</span><span class="n">close</span><span class="p">(</span><span class="n">stderr</span><span class="o">.</span><span class="n">fileno</span><span class="p">())</span>
|
||||
</pre></div>
|
||||
</div>
|
||||
<p>或者也可以使用常量 0,1,2 代替。</p>
|
||||
</section>
|
||||
</section>
|
||||
<section id="network-internet-programming">
|
||||
<h2><a class="toc-backref" href="#id27">网络 / Internet 编程</a><a class="headerlink" href="#network-internet-programming" title="永久链接至标题">¶</a></h2>
|
||||
<section id="what-www-tools-are-there-for-python">
|
||||
<h3><a class="toc-backref" href="#id28">Python 中的 WWW 工具是什么?</a><a class="headerlink" href="#what-www-tools-are-there-for-python" title="永久链接至标题">¶</a></h3>
|
||||
<p>参阅代码库参考手册中 <a class="reference internal" href="../library/internet.html#internet"><span class="std std-ref">互联网协议和支持</span></a> 和 <a class="reference internal" href="../library/netdata.html#netdata"><span class="std std-ref">互联网数据处理</span></a> 这两章的内容。Python 有大量模块来帮助你构建服务端和客户端 web 系统。</p>
|
||||
<p>Paul Boddie 维护了一份可用框架的概览,见 <a class="reference external" href="https://wiki.python.org/moin/WebProgramming">https://wiki.python.org/moin/WebProgramming</a> 。</p>
|
||||
<p>Cameron Laird 维护了一份关于 Python web 技术的实用网页的集合,见 <a class="reference external" href="http://phaseit.net/claird/comp.lang.python/web_python">http://phaseit.net/claird/comp.lang.python/web_python</a> 。</p>
|
||||
</section>
|
||||
<section id="how-can-i-mimic-cgi-form-submission-method-post">
|
||||
<h3><a class="toc-backref" href="#id29">怎样模拟发送 CGI 表单(METHOD=POST)?</a><a class="headerlink" href="#how-can-i-mimic-cgi-form-submission-method-post" title="永久链接至标题">¶</a></h3>
|
||||
<p>我需要通过 POST 表单获取网页,有什么代码能简单做到吗?</p>
|
||||
<p>是的,这里有一个使用 urllib.request 的简单例子:</p>
|
||||
<div class="highlight-python3 notranslate"><div class="highlight"><pre><span></span><span class="ch">#!/usr/local/bin/python</span>
|
||||
|
||||
<span class="kn">import</span> <span class="nn">urllib.request</span>
|
||||
|
||||
<span class="c1"># build the query string</span>
|
||||
<span class="n">qs</span> <span class="o">=</span> <span class="s2">"First=Josephine&MI=Q&Last=Public"</span>
|
||||
|
||||
<span class="c1"># connect and send the server a path</span>
|
||||
<span class="n">req</span> <span class="o">=</span> <span class="n">urllib</span><span class="o">.</span><span class="n">request</span><span class="o">.</span><span class="n">urlopen</span><span class="p">(</span><span class="s1">'http://www.some-server.out-there'</span>
|
||||
<span class="s1">'/cgi-bin/some-cgi-script'</span><span class="p">,</span> <span class="n">data</span><span class="o">=</span><span class="n">qs</span><span class="p">)</span>
|
||||
<span class="k">with</span> <span class="n">req</span><span class="p">:</span>
|
||||
<span class="n">msg</span><span class="p">,</span> <span class="n">hdrs</span> <span class="o">=</span> <span class="n">req</span><span class="o">.</span><span class="n">read</span><span class="p">(),</span> <span class="n">req</span><span class="o">.</span><span class="n">info</span><span class="p">()</span>
|
||||
</pre></div>
|
||||
</div>
|
||||
<p>注意,通常在百分号编码的 POST 操作中,查询字符串必须使用 <a class="reference internal" href="../library/urllib.parse.html#urllib.parse.urlencode" title="urllib.parse.urlencode"><code class="xref py py-func docutils literal notranslate"><span class="pre">urllib.parse.urlencode()</span></code></a> 处理一下。举个例子,如果要发送 <code class="docutils literal notranslate"><span class="pre">name=Guy</span> <span class="pre">Steele,</span> <span class="pre">Jr.</span></code> 的话:</p>
|
||||
<div class="highlight-python3 notranslate"><div class="highlight"><pre><span></span><span class="gp">>>> </span><span class="kn">import</span> <span class="nn">urllib.parse</span>
|
||||
<span class="gp">>>> </span><span class="n">urllib</span><span class="o">.</span><span class="n">parse</span><span class="o">.</span><span class="n">urlencode</span><span class="p">({</span><span class="s1">'name'</span><span class="p">:</span> <span class="s1">'Guy Steele, Jr.'</span><span class="p">})</span>
|
||||
<span class="go">'name=Guy+Steele%2C+Jr.'</span>
|
||||
</pre></div>
|
||||
</div>
|
||||
<div class="admonition seealso">
|
||||
<p class="admonition-title">参见</p>
|
||||
<p>查看 <a class="reference internal" href="../howto/urllib2.html#urllib-howto"><span class="std std-ref">如何利用 urllib 包获取网络资源</span></a> 获取更多示例。</p>
|
||||
</div>
|
||||
</section>
|
||||
<section id="what-module-should-i-use-to-help-with-generating-html">
|
||||
<h3><a class="toc-backref" href="#id30">生成 HTML 需要使用什么模块?</a><a class="headerlink" href="#what-module-should-i-use-to-help-with-generating-html" title="永久链接至标题">¶</a></h3>
|
||||
<p>你可以在 <a class="reference external" href="https://wiki.python.org/moin/WebProgramming">Web 编程 wiki 页面</a> 找到许多有用的链接。</p>
|
||||
</section>
|
||||
<section id="how-do-i-send-mail-from-a-python-script">
|
||||
<h3><a class="toc-backref" href="#id31">怎样使用 Python 脚本发送邮件?</a><a class="headerlink" href="#how-do-i-send-mail-from-a-python-script" title="永久链接至标题">¶</a></h3>
|
||||
<p>使用 <a class="reference internal" href="../library/smtplib.html#module-smtplib" title="smtplib: SMTP protocol client (requires sockets)."><code class="xref py py-mod docutils literal notranslate"><span class="pre">smtplib</span></code></a> 标准库模块。</p>
|
||||
<p>下面是一个很简单的交互式发送邮件的代码。这个方法适用于任何支持 SMTP 协议的主机。</p>
|
||||
<div class="highlight-python3 notranslate"><div class="highlight"><pre><span></span><span class="kn">import</span> <span class="nn">sys</span><span class="o">,</span> <span class="nn">smtplib</span>
|
||||
|
||||
<span class="n">fromaddr</span> <span class="o">=</span> <span class="nb">input</span><span class="p">(</span><span class="s2">"From: "</span><span class="p">)</span>
|
||||
<span class="n">toaddrs</span> <span class="o">=</span> <span class="nb">input</span><span class="p">(</span><span class="s2">"To: "</span><span class="p">)</span><span class="o">.</span><span class="n">split</span><span class="p">(</span><span class="s1">','</span><span class="p">)</span>
|
||||
<span class="nb">print</span><span class="p">(</span><span class="s2">"Enter message, end with ^D:"</span><span class="p">)</span>
|
||||
<span class="n">msg</span> <span class="o">=</span> <span class="s1">''</span>
|
||||
<span class="k">while</span> <span class="kc">True</span><span class="p">:</span>
|
||||
<span class="n">line</span> <span class="o">=</span> <span class="n">sys</span><span class="o">.</span><span class="n">stdin</span><span class="o">.</span><span class="n">readline</span><span class="p">()</span>
|
||||
<span class="k">if</span> <span class="ow">not</span> <span class="n">line</span><span class="p">:</span>
|
||||
<span class="k">break</span>
|
||||
<span class="n">msg</span> <span class="o">+=</span> <span class="n">line</span>
|
||||
|
||||
<span class="c1"># The actual mail send</span>
|
||||
<span class="n">server</span> <span class="o">=</span> <span class="n">smtplib</span><span class="o">.</span><span class="n">SMTP</span><span class="p">(</span><span class="s1">'localhost'</span><span class="p">)</span>
|
||||
<span class="n">server</span><span class="o">.</span><span class="n">sendmail</span><span class="p">(</span><span class="n">fromaddr</span><span class="p">,</span> <span class="n">toaddrs</span><span class="p">,</span> <span class="n">msg</span><span class="p">)</span>
|
||||
<span class="n">server</span><span class="o">.</span><span class="n">quit</span><span class="p">()</span>
|
||||
</pre></div>
|
||||
</div>
|
||||
<p>在 Unix 系统中还可以使用 sendmail。sendmail 程序的位置在不同系统中不一样,有时是在 <code class="docutils literal notranslate"><span class="pre">/usr/lib/sendmail</span></code>,有时是在 <code class="docutils literal notranslate"><span class="pre">/usr/sbin/sendmail</span></code>。sendmail 手册页面会对你有所帮助。以下是示例代码:</p>
|
||||
<div class="highlight-python3 notranslate"><div class="highlight"><pre><span></span><span class="kn">import</span> <span class="nn">os</span>
|
||||
|
||||
<span class="n">SENDMAIL</span> <span class="o">=</span> <span class="s2">"/usr/sbin/sendmail"</span> <span class="c1"># sendmail location</span>
|
||||
<span class="n">p</span> <span class="o">=</span> <span class="n">os</span><span class="o">.</span><span class="n">popen</span><span class="p">(</span><span class="s2">"</span><span class="si">%s</span><span class="s2"> -t -i"</span> <span class="o">%</span> <span class="n">SENDMAIL</span><span class="p">,</span> <span class="s2">"w"</span><span class="p">)</span>
|
||||
<span class="n">p</span><span class="o">.</span><span class="n">write</span><span class="p">(</span><span class="s2">"To: receiver@example.com</span><span class="se">\n</span><span class="s2">"</span><span class="p">)</span>
|
||||
<span class="n">p</span><span class="o">.</span><span class="n">write</span><span class="p">(</span><span class="s2">"Subject: test</span><span class="se">\n</span><span class="s2">"</span><span class="p">)</span>
|
||||
<span class="n">p</span><span class="o">.</span><span class="n">write</span><span class="p">(</span><span class="s2">"</span><span class="se">\n</span><span class="s2">"</span><span class="p">)</span> <span class="c1"># blank line separating headers from body</span>
|
||||
<span class="n">p</span><span class="o">.</span><span class="n">write</span><span class="p">(</span><span class="s2">"Some text</span><span class="se">\n</span><span class="s2">"</span><span class="p">)</span>
|
||||
<span class="n">p</span><span class="o">.</span><span class="n">write</span><span class="p">(</span><span class="s2">"some more text</span><span class="se">\n</span><span class="s2">"</span><span class="p">)</span>
|
||||
<span class="n">sts</span> <span class="o">=</span> <span class="n">p</span><span class="o">.</span><span class="n">close</span><span class="p">()</span>
|
||||
<span class="k">if</span> <span class="n">sts</span> <span class="o">!=</span> <span class="mi">0</span><span class="p">:</span>
|
||||
<span class="nb">print</span><span class="p">(</span><span class="s2">"Sendmail exit status"</span><span class="p">,</span> <span class="n">sts</span><span class="p">)</span>
|
||||
</pre></div>
|
||||
</div>
|
||||
</section>
|
||||
<section id="how-do-i-avoid-blocking-in-the-connect-method-of-a-socket">
|
||||
<h3><a class="toc-backref" href="#id32">socket 的 connect() 方法怎样避免阻塞?</a><a class="headerlink" href="#how-do-i-avoid-blocking-in-the-connect-method-of-a-socket" title="永久链接至标题">¶</a></h3>
|
||||
<p>通常会用 <a class="reference internal" href="../library/select.html#module-select" title="select: Wait for I/O completion on multiple streams."><code class="xref py py-mod docutils literal notranslate"><span class="pre">select</span></code></a> 模块处理 socket 异步 I/O。</p>
|
||||
<p>要避免 TCP 连接阻塞,你可以设置将 socket 设置为非阻塞模式。此时当调用 <code class="docutils literal notranslate"><span class="pre">connect()</span></code> 时,要么连接会立刻建立好(几乎不可能),要么会收到一个包含了错误码 <code class="docutils literal notranslate"><span class="pre">.error</span></code> 的异常。<code class="docutils literal notranslate"><span class="pre">errno.EINPROGRESS</span></code> 表示连接正在进行,但还没有完成。不同的系统会返回不同的值,所以你需要确认你使用的系统会返回什么。</p>
|
||||
<p>你可以使用 <code class="docutils literal notranslate"><span class="pre">connect_ex()</span></code> 方法来避免产生异常。这个方法只会返回错误码。如果需要轮询的话,你可以再次调用 <code class="docutils literal notranslate"><span class="pre">connect_ex()</span></code> —— <code class="docutils literal notranslate"><span class="pre">0</span></code> 或 <code class="docutils literal notranslate"><span class="pre">errno.EISCONN</span></code> 表示连接已建立,或者你也可以用 select 检查这个 socket 是否可写。</p>
|
||||
<div class="admonition note">
|
||||
<p class="admonition-title">注解</p>
|
||||
<p><a class="reference internal" href="../library/asyncore.html#module-asyncore" title="asyncore: A base class for developing asynchronous socket handling services."><code class="xref py py-mod docutils literal notranslate"><span class="pre">asyncore</span></code></a> 模块提供了编写非阻塞网络代码框架性的方法。第三方的 <a class="reference external" href="https://twistedmatrix.com/trac/">Twisted</a> 库也很常用且功能强大。</p>
|
||||
</div>
|
||||
</section>
|
||||
</section>
|
||||
<section id="databases">
|
||||
<h2><a class="toc-backref" href="#id33">数据库</a><a class="headerlink" href="#databases" title="永久链接至标题">¶</a></h2>
|
||||
<section id="are-there-any-interfaces-to-database-packages-in-python">
|
||||
<h3><a class="toc-backref" href="#id34">Python 中有数据库包的接口吗?</a><a class="headerlink" href="#are-there-any-interfaces-to-database-packages-in-python" title="永久链接至标题">¶</a></h3>
|
||||
<p>有的。</p>
|
||||
<p>标准 Python 还包含了基于磁盘的哈希接口例如 <a class="reference internal" href="../library/dbm.html#module-dbm.ndbm" title="dbm.ndbm: The standard "database" interface, based on ndbm. (Unix)"><code class="xref py py-mod docutils literal notranslate"><span class="pre">DBM</span></code></a> 和 <a class="reference internal" href="../library/dbm.html#module-dbm.gnu" title="dbm.gnu: GNU's reinterpretation of dbm. (Unix)"><code class="xref py py-mod docutils literal notranslate"><span class="pre">GDBM</span></code></a> 。除此之外还有 <a class="reference internal" href="../library/sqlite3.html#module-sqlite3" title="sqlite3: A DB-API 2.0 implementation using SQLite 3.x."><code class="xref py py-mod docutils literal notranslate"><span class="pre">sqlite3</span></code></a> 模块,该模块提供了一个轻量级的基于磁盘的关系型数据库。</p>
|
||||
<p>大多数关系型数据库都已经支持。查看 <a class="reference external" href="https://wiki.python.org/moin/DatabaseProgramming">数据库编程 wiki 页面</a> 获取更多信息。</p>
|
||||
</section>
|
||||
<section id="how-do-you-implement-persistent-objects-in-python">
|
||||
<h3><a class="toc-backref" href="#id35">在 Python 中如何实现持久化对象?</a><a class="headerlink" href="#how-do-you-implement-persistent-objects-in-python" title="永久链接至标题">¶</a></h3>
|
||||
<p><a class="reference internal" href="../library/pickle.html#module-pickle" title="pickle: Convert Python objects to streams of bytes and back."><code class="xref py py-mod docutils literal notranslate"><span class="pre">pickle</span></code></a> 库模块以一种非常通用的方式解决了这个问题(虽然你依然不能用它保存打开的文件、套接字或窗口之类的东西),此外 <a class="reference internal" href="../library/shelve.html#module-shelve" title="shelve: Python object persistence."><code class="xref py py-mod docutils literal notranslate"><span class="pre">shelve</span></code></a> 库模块可使用 pickle 和 (g)dbm 来创建包含任意 Python 对象的持久化映射。</p>
|
||||
</section>
|
||||
</section>
|
||||
<section id="mathematics-and-numerics">
|
||||
<h2><a class="toc-backref" href="#id36">数学和数字</a><a class="headerlink" href="#mathematics-and-numerics" title="永久链接至标题">¶</a></h2>
|
||||
<section id="how-do-i-generate-random-numbers-in-python">
|
||||
<h3><a class="toc-backref" href="#id37">Python 中怎样生成随机数?</a><a class="headerlink" href="#how-do-i-generate-random-numbers-in-python" title="永久链接至标题">¶</a></h3>
|
||||
<p><a class="reference internal" href="../library/random.html#module-random" title="random: Generate pseudo-random numbers with various common distributions."><code class="xref py py-mod docutils literal notranslate"><span class="pre">random</span></code></a> 标准库模块实现了随机数生成器,使用起来非常简单:</p>
|
||||
<div class="highlight-python3 notranslate"><div class="highlight"><pre><span></span><span class="kn">import</span> <span class="nn">random</span>
|
||||
<span class="n">random</span><span class="o">.</span><span class="n">random</span><span class="p">()</span>
|
||||
</pre></div>
|
||||
</div>
|
||||
<p>这个函数会返回 [0, 1) 之间的随机浮点数。</p>
|
||||
<p>该模块中还有许多其他的专门的生成器,例如:</p>
|
||||
<ul class="simple">
|
||||
<li><p><code class="docutils literal notranslate"><span class="pre">randrange(a,</span> <span class="pre">b)</span></code> 返回 [a, b) 区间内的一个整型数。</p></li>
|
||||
<li><p><code class="docutils literal notranslate"><span class="pre">uniform(a,</span> <span class="pre">b)</span></code> 返回 [a, b) 区间之间的浮点数。</p></li>
|
||||
<li><p><code class="docutils literal notranslate"><span class="pre">normalvariate(mean,</span> <span class="pre">sdev)</span></code> 使用正态(高斯)分布采样。</p></li>
|
||||
</ul>
|
||||
<p>还有一些高级函数直接对序列进行操作,例如:</p>
|
||||
<ul class="simple">
|
||||
<li><p><code class="docutils literal notranslate"><span class="pre">choice(S)</span></code> 从给定的序列中随机选择一个元素。</p></li>
|
||||
<li><p><code class="docutils literal notranslate"><span class="pre">shuffle(L)</span></code> 对列表进行原地重排,也就是说随机打乱。</p></li>
|
||||
</ul>
|
||||
<p>还有 <code class="docutils literal notranslate"><span class="pre">Random</span></code> 类,你可以将其实例化,用来创建多个独立的随机数生成器。</p>
|
||||
</section>
|
||||
</section>
|
||||
</section>
|
||||
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="sphinxsidebar" role="navigation" aria-label="main navigation">
|
||||
<div class="sphinxsidebarwrapper">
|
||||
<h3><a href="../contents.html">目录</a></h3>
|
||||
<ul>
|
||||
<li><a class="reference internal" href="#">代码库和插件 FAQ</a><ul>
|
||||
<li><a class="reference internal" href="#general-library-questions">通用的代码库问题</a></li>
|
||||
<li><a class="reference internal" href="#common-tasks">通用任务</a></li>
|
||||
<li><a class="reference internal" href="#threads">线程相关</a></li>
|
||||
<li><a class="reference internal" href="#input-and-output">输入输出</a></li>
|
||||
<li><a class="reference internal" href="#network-internet-programming">网络 / Internet 编程</a></li>
|
||||
<li><a class="reference internal" href="#databases">数据库</a></li>
|
||||
<li><a class="reference internal" href="#mathematics-and-numerics">数学和数字</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<h4>上一个主题</h4>
|
||||
<p class="topless"><a href="design.html"
|
||||
title="上一章">设计和历史常见问题</a></p>
|
||||
<h4>下一个主题</h4>
|
||||
<p class="topless"><a href="extending.html"
|
||||
title="下一章">扩展/嵌入常见问题</a></p>
|
||||
<div role="note" aria-label="source link">
|
||||
<h3>本页</h3>
|
||||
<ul class="this-page-menu">
|
||||
<li><a href="../bugs.html">报告 Bug</a></li>
|
||||
<li>
|
||||
<a href="https://github.com/python/cpython/blob/3.8/Doc/faq/library.rst"
|
||||
rel="nofollow">显示源代码
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="clearer"></div>
|
||||
</div>
|
||||
<div class="related" role="navigation" aria-label="related navigation">
|
||||
<h3>导航</h3>
|
||||
<ul>
|
||||
<li class="right" style="margin-right: 10px">
|
||||
<a href="../genindex.html" title="总目录"
|
||||
>索引</a></li>
|
||||
<li class="right" >
|
||||
<a href="../py-modindex.html" title="Python 模块索引"
|
||||
>模块</a> |</li>
|
||||
<li class="right" >
|
||||
<a href="extending.html" title="扩展/嵌入常见问题"
|
||||
>下一页</a> |</li>
|
||||
<li class="right" >
|
||||
<a href="design.html" title="设计和历史常见问题"
|
||||
>上一页</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.8.20 Documentation</a> »
|
||||
</li>
|
||||
|
||||
<li class="nav-item nav-item-1"><a href="index.html" >Python 常见问题</a> »</li>
|
||||
<li class="right">
|
||||
|
||||
|
||||
<div class="inline-search" role="search">
|
||||
<form class="inline-search" action="../search.html" method="get">
|
||||
<input placeholder="快速搜索" aria-label="快速搜索" type="text" name="q" />
|
||||
<input type="submit" value="转向" />
|
||||
<input type="hidden" name="check_keywords" value="yes" />
|
||||
<input type="hidden" name="area" value="default" />
|
||||
</form>
|
||||
</div>
|
||||
|
|
||||
</li>
|
||||
|
||||
</ul>
|
||||
</div>
|
||||
<div class="footer">
|
||||
© <a href="../copyright.html">版权所有</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 />
|
||||
|
||||
<br />
|
||||
|
||||
The Python Software Foundation is a non-profit corporation.
|
||||
<a href="https://www.python.org/psf/donations/">Please donate.</a>
|
||||
<br />
|
||||
<br />
|
||||
|
||||
最后更新于 12月 09, 2024.
|
||||
<a href="https://docs.python.org/3/bugs.html">Found a bug</a>?
|
||||
<br />
|
||||
|
||||
Created using <a href="https://www.sphinx-doc.org/">Sphinx</a> 2.4.4.
|
||||
</div>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
1575
web/python-docs/faq/programming.html
Normal file
1575
web/python-docs/faq/programming.html
Normal file
File diff suppressed because it is too large
Load Diff
408
web/python-docs/faq/windows.html
Normal file
408
web/python-docs/faq/windows.html
Normal file
@@ -0,0 +1,408 @@
|
||||
|
||||
<!DOCTYPE html>
|
||||
|
||||
<html xmlns="http://www.w3.org/1999/xhtml" lang="zh_CN">
|
||||
<head>
|
||||
<meta charset="utf-8" /><meta name="generator" content="Docutils 0.17.1: http://docutils.sourceforge.net/" />
|
||||
|
||||
<title>Python在Windows上的常见问题 — Python 3.8.20 文档</title><meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
|
||||
<link rel="stylesheet" href="../_static/pydoctheme.css" type="text/css" />
|
||||
<link rel="stylesheet" href="../_static/pygments.css" type="text/css" />
|
||||
|
||||
<script id="documentation_options" data-url_root="../" src="../_static/documentation_options.js"></script>
|
||||
<script src="../_static/jquery.js"></script>
|
||||
<script src="../_static/underscore.js"></script>
|
||||
<script src="../_static/doctools.js"></script>
|
||||
<script src="../_static/language_data.js"></script>
|
||||
<script src="../_static/translations.js"></script>
|
||||
|
||||
<script src="../_static/sidebar.js"></script>
|
||||
|
||||
<link rel="search" type="application/opensearchdescription+xml"
|
||||
title="在 Python 3.8.20 文档 中搜索"
|
||||
href="../_static/opensearch.xml"/>
|
||||
<link rel="author" title="关于这些文档" href="../about.html" />
|
||||
<link rel="index" title="索引" href="../genindex.html" />
|
||||
<link rel="search" title="搜索" href="../search.html" />
|
||||
<link rel="copyright" title="版权所有" href="../copyright.html" />
|
||||
<link rel="next" title="图形用户界面(GUI)常见问题" href="gui.html" />
|
||||
<link rel="prev" title="扩展/嵌入常见问题" href="extending.html" />
|
||||
<link rel="canonical" href="https://docs.python.org/3/faq/windows.html" />
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<style>
|
||||
@media only screen {
|
||||
table.full-width-table {
|
||||
width: 100%;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
<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>
|
||||
|
||||
</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" />
|
||||
<label for="menuToggler" class="toggler__label">
|
||||
<span></span>
|
||||
</label>
|
||||
<nav class="nav-content" role="navigation">
|
||||
<a href="https://www.python.org/" class="nav-logo">
|
||||
<img src="../_static/py.svg" alt="Logo"/>
|
||||
</a>
|
||||
<div class="version_switcher_placeholder"></div>
|
||||
<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"
|
||||
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" fill="#444"></path>
|
||||
</svg>
|
||||
<input type="text" name="q" aria-label="快速搜索"/>
|
||||
<input type="submit" value="转向"/>
|
||||
</form>
|
||||
</nav>
|
||||
<div class="menu-wrapper">
|
||||
<nav class="menu" role="navigation" aria-label="main navigation">
|
||||
<div class="language_switcher_placeholder"></div>
|
||||
<h3><a href="../contents.html">目录</a></h3>
|
||||
<ul>
|
||||
<li><a class="reference internal" href="#">Python在Windows上的常见问题</a><ul>
|
||||
<li><a class="reference internal" href="#how-do-i-run-a-python-program-under-windows">我怎样在Windows下运行一个Python程序?</a></li>
|
||||
<li><a class="reference internal" href="#how-do-i-make-python-scripts-executable">我怎么让 Python 脚本可执行?</a></li>
|
||||
<li><a class="reference internal" href="#why-does-python-sometimes-take-so-long-to-start">为什么有时候 Python 程序会启动缓慢?</a></li>
|
||||
<li><a class="reference internal" href="#how-do-i-make-an-executable-from-a-python-script">我怎样使用 Python 脚本制作可执行文件?</a></li>
|
||||
<li><a class="reference internal" href="#is-a-pyd-file-the-same-as-a-dll"><code class="docutils literal notranslate"><span class="pre">*.pyd</span></code> 文件和 DLL 文件相同吗?</a></li>
|
||||
<li><a class="reference internal" href="#how-can-i-embed-python-into-a-windows-application">我怎样将 Python 嵌入一个 Windows 程序?</a></li>
|
||||
<li><a class="reference internal" href="#how-do-i-keep-editors-from-inserting-tabs-into-my-python-source">如何让编辑器不要在我的 Python 源代码中插入 tab ?</a></li>
|
||||
<li><a class="reference internal" href="#how-do-i-check-for-a-keypress-without-blocking">如何在不阻塞的情况下检查按键?</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<h4>上一个主题</h4>
|
||||
<p class="topless"><a href="extending.html"
|
||||
title="上一章">扩展/嵌入常见问题</a></p>
|
||||
<h4>下一个主题</h4>
|
||||
<p class="topless"><a href="gui.html"
|
||||
title="下一章">图形用户界面(GUI)常见问题</a></p>
|
||||
<div role="note" aria-label="source link">
|
||||
<h3>本页</h3>
|
||||
<ul class="this-page-menu">
|
||||
<li><a href="../bugs.html">报告 Bug</a></li>
|
||||
<li>
|
||||
<a href="https://github.com/python/cpython/blob/3.8/Doc/faq/windows.rst"
|
||||
rel="nofollow">显示源代码
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</nav>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="outdated-warning" style="padding: .5em; text-align: center; background-color: #FFBABA; color: #6A0E0E;">
|
||||
这个文档所针对的是一个已不再受支持的 Python 旧版本。
|
||||
你应当升级版本,并阅读
|
||||
<a href="/3/faq/windows.html"> Python 当前稳定版本的文档</a>.
|
||||
</div>
|
||||
|
||||
<div class="related" role="navigation" aria-label="related navigation">
|
||||
<h3>导航</h3>
|
||||
<ul>
|
||||
<li class="right" style="margin-right: 10px">
|
||||
<a href="../genindex.html" title="总目录"
|
||||
accesskey="I">索引</a></li>
|
||||
<li class="right" >
|
||||
<a href="../py-modindex.html" title="Python 模块索引"
|
||||
>模块</a> |</li>
|
||||
<li class="right" >
|
||||
<a href="gui.html" title="图形用户界面(GUI)常见问题"
|
||||
accesskey="N">下一页</a> |</li>
|
||||
<li class="right" >
|
||||
<a href="extending.html" title="扩展/嵌入常见问题"
|
||||
accesskey="P">上一页</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.8.20 Documentation</a> »
|
||||
</li>
|
||||
|
||||
<li class="nav-item nav-item-1"><a href="index.html" accesskey="U">Python 常见问题</a> »</li>
|
||||
<li class="right">
|
||||
|
||||
|
||||
<div class="inline-search" role="search">
|
||||
<form class="inline-search" action="../search.html" method="get">
|
||||
<input placeholder="快速搜索" aria-label="快速搜索" type="text" name="q" />
|
||||
<input type="submit" value="转向" />
|
||||
<input type="hidden" name="check_keywords" value="yes" />
|
||||
<input type="hidden" name="area" value="default" />
|
||||
</form>
|
||||
</div>
|
||||
|
|
||||
</li>
|
||||
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<div class="document">
|
||||
<div class="documentwrapper">
|
||||
<div class="bodywrapper">
|
||||
<div class="body" role="main">
|
||||
|
||||
<section id="python-on-windows-faq">
|
||||
<span id="windows-faq"></span><h1><a class="toc-backref" href="#id2">Python在Windows上的常见问题</a><a class="headerlink" href="#python-on-windows-faq" title="永久链接至标题">¶</a></h1>
|
||||
<div class="contents topic" id="id1">
|
||||
<p class="topic-title">目录</p>
|
||||
<ul class="simple">
|
||||
<li><p><a class="reference internal" href="#python-on-windows-faq" id="id2">Python在Windows上的常见问题</a></p>
|
||||
<ul>
|
||||
<li><p><a class="reference internal" href="#how-do-i-run-a-python-program-under-windows" id="id3">我怎样在Windows下运行一个Python程序?</a></p></li>
|
||||
<li><p><a class="reference internal" href="#how-do-i-make-python-scripts-executable" id="id4">我怎么让 Python 脚本可执行?</a></p></li>
|
||||
<li><p><a class="reference internal" href="#why-does-python-sometimes-take-so-long-to-start" id="id5">为什么有时候 Python 程序会启动缓慢?</a></p></li>
|
||||
<li><p><a class="reference internal" href="#how-do-i-make-an-executable-from-a-python-script" id="id6">我怎样使用 Python 脚本制作可执行文件?</a></p></li>
|
||||
<li><p><a class="reference internal" href="#is-a-pyd-file-the-same-as-a-dll" id="id7"><code class="docutils literal notranslate"><span class="pre">*.pyd</span></code> 文件和 DLL 文件相同吗?</a></p></li>
|
||||
<li><p><a class="reference internal" href="#how-can-i-embed-python-into-a-windows-application" id="id8">我怎样将 Python 嵌入一个 Windows 程序?</a></p></li>
|
||||
<li><p><a class="reference internal" href="#how-do-i-keep-editors-from-inserting-tabs-into-my-python-source" id="id9">如何让编辑器不要在我的 Python 源代码中插入 tab ?</a></p></li>
|
||||
<li><p><a class="reference internal" href="#how-do-i-check-for-a-keypress-without-blocking" id="id10">如何在不阻塞的情况下检查按键?</a></p></li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
<section id="how-do-i-run-a-python-program-under-windows">
|
||||
<span id="faq-run-program-under-windows"></span><h2><a class="toc-backref" href="#id3">我怎样在Windows下运行一个Python程序?</a><a class="headerlink" href="#how-do-i-run-a-python-program-under-windows" title="永久链接至标题">¶</a></h2>
|
||||
<p>这不一定是一个简单的问题。如果你已经熟悉在Windows的命令行中运行程序的方法,一切都显而易见;不然的话,你也许需要额外获得些许指导。</p>
|
||||
<p>除非你在使用某种集成开发环境,否则你将会在被称为“DOS 窗口”或“命令提示符窗口”的地方 <em>输入</em> Windows 命令。 通常你可以在搜索栏搜索 <code class="docutils literal notranslate"><span class="pre">cmd</span></code> 来创建这种窗口。 你应该能够识别你何时打开了这样的窗口,因为你将看到一个 Windows“命令提示符”,通常看起来是这样:</p>
|
||||
<div class="highlight-doscon notranslate"><div class="highlight"><pre><span></span><span class="gp">C:\></span>
|
||||
</pre></div>
|
||||
</div>
|
||||
<p>前面的字母可能会不同,而且后面有可能会有其他东西,所以你也许会看到类似这样的东西:</p>
|
||||
<div class="highlight-doscon notranslate"><div class="highlight"><pre><span></span><span class="gp">D:\YourName\Projects\Python></span>
|
||||
</pre></div>
|
||||
</div>
|
||||
<p>出现的内容具体取决与你的电脑如何设置和最近用它做的事。 当你启动了这样一个窗口后,就可以开始运行Python程序了。</p>
|
||||
<p>Python 脚本需要被另外一个叫做 Python <em>解释器</em> 的程序来处理。 解释器读取脚本,把它编译成字节码,然后执行字节码来运行你的程序。 所以怎样安排解释器来处理你的 Python 脚本呢?</p>
|
||||
<p>首先,确保命令窗口能够将“py”识别为指令来开启解释器。 如果你打开过一个命令窗口, 尝试输入命令 <code class="docutils literal notranslate"><span class="pre">py</span></code> 然后按回车:</p>
|
||||
<div class="highlight-doscon notranslate"><div class="highlight"><pre><span></span><span class="gp">C:\Users\YourName></span> py
|
||||
</pre></div>
|
||||
</div>
|
||||
<p>然后你应当看见类似类似这样的东西:</p>
|
||||
<div class="highlight-pycon notranslate"><div class="highlight"><pre><span></span><span class="go">Python 3.6.4 (v3.6.4:d48eceb, Dec 19 2017, 06:04:45) [MSC v.1900 32 bit (Intel)] on win32</span>
|
||||
<span class="go">Type "help", "copyright", "credits" or "license" for more information.</span>
|
||||
<span class="gp">>>></span>
|
||||
</pre></div>
|
||||
</div>
|
||||
<p>解释器已经以“交互模式”打开。这意味着你可以交互输入Python语句或表达式,并在等待时执行或评估它们。这是Python最强大的功能之一。输入几个表达式并看看结果:</p>
|
||||
<div class="highlight-pycon notranslate"><div class="highlight"><pre><span></span><span class="gp">>>> </span><span class="nb">print</span><span class="p">(</span><span class="s2">"Hello"</span><span class="p">)</span>
|
||||
<span class="go">Hello</span>
|
||||
<span class="gp">>>> </span><span class="s2">"Hello"</span> <span class="o">*</span> <span class="mi">3</span>
|
||||
<span class="go">'HelloHelloHello'</span>
|
||||
</pre></div>
|
||||
</div>
|
||||
<p>许多人把交互模式当作方便和高度可编程的计算器。 想结束交互式Python会话时,调用 <a class="reference internal" href="../library/constants.html#exit" title="exit"><code class="xref py py-func docutils literal notranslate"><span class="pre">exit()</span></code></a> 函数,或者按住 <kbd class="kbd docutils literal notranslate">Ctrl</kbd> 键时输入 <kbd class="kbd docutils literal notranslate">Z</kbd> ,之后按 <kbd class="kbd docutils literal notranslate">Enter</kbd> 键返回Windows命令提示符。</p>
|
||||
<p>你可能发现在开始菜单有这样一个条目 <span class="menuselection">开始 ‣ 所有程序 ‣ Python 3.x ‣ Python (命令行)</span>, 运行它后会出现一个有着 <code class="docutils literal notranslate"><span class="pre">>>></span></code> 提示的新窗口。 在此之后,如果调用 <a class="reference internal" href="../library/constants.html#exit" title="exit"><code class="xref py py-func docutils literal notranslate"><span class="pre">exit()</span></code></a> 函数或按 <kbd class="kbd docutils literal notranslate">Ctrl-Z</kbd> 组合键后窗口将会消失。 Windows 会在这个窗口中运行一个“python”命令,并且在你终止解释器的时候关闭它。</p>
|
||||
<p>现在我们知道 <code class="docutils literal notranslate"><span class="pre">py</span></code> 命令已经被识别,可以输入 Python 脚本了。 你需要提供 Python 脚本的绝对路径或相对路径。 假设 Python 脚本位于桌面上并命名为 <code class="docutils literal notranslate"><span class="pre">hello.py</span></code>,并且命令提示符在用户主目录打开,那么可以看到类似于这样的东西:</p>
|
||||
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>C:\Users\YourName>
|
||||
</pre></div>
|
||||
</div>
|
||||
<p>那么现在可以让 <code class="docutils literal notranslate"><span class="pre">py</span></code> 命令执行你的脚本,只需要输入 <code class="docutils literal notranslate"><span class="pre">py</span></code> 和脚本路径:</p>
|
||||
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>C:\Users\YourName> py Desktop\hello.py
|
||||
hello
|
||||
</pre></div>
|
||||
</div>
|
||||
</section>
|
||||
<section id="how-do-i-make-python-scripts-executable">
|
||||
<h2><a class="toc-backref" href="#id4">我怎么让 Python 脚本可执行?</a><a class="headerlink" href="#how-do-i-make-python-scripts-executable" title="永久链接至标题">¶</a></h2>
|
||||
<p>在 Windows 上,标准 Python 安装程序已将 .py 扩展名与文件类型 (Python.File) 相关联,并为该文件类型提供运行解释器的打开命令 (<code class="docutils literal notranslate"><span class="pre">D:\Program</span> <span class="pre">Files\Python\python.exe</span> <span class="pre">"%1"</span> <span class="pre">%*</span></code>) 。 这足以使脚本在命令提示符下作为“foo.py”命令被执行。 如果希望通过简单地键入“foo”而无需输入文件扩展名来执行脚本,则需要将 .py 添加到 PATHEXT 环境变量中。</p>
|
||||
</section>
|
||||
<section id="why-does-python-sometimes-take-so-long-to-start">
|
||||
<h2><a class="toc-backref" href="#id5">为什么有时候 Python 程序会启动缓慢?</a><a class="headerlink" href="#why-does-python-sometimes-take-so-long-to-start" title="永久链接至标题">¶</a></h2>
|
||||
<p>通常,Python 在 Windows 上启动得很快,但偶尔会有错误报告说 Python 突然需要很长时间才能启动。更令人费解的是,在其他配置相同的 Windows 系统上,Python 却可以工作得很好。</p>
|
||||
<p>该问题可能是由于计算机上的杀毒软件配置错误造成的。当将病毒扫描配置为监视文件系统中所有读取行为时,一些杀毒扫描程序会导致两个数量级的启动开销。请检查你系统安装的杀毒扫描程序的配置,确保两台机它们是同样的配置。已知的, McAfee 杀毒软件在将它设置为扫描所有文件系统访问时,会产生这个问题。</p>
|
||||
</section>
|
||||
<section id="how-do-i-make-an-executable-from-a-python-script">
|
||||
<h2><a class="toc-backref" href="#id6">我怎样使用 Python 脚本制作可执行文件?</a><a class="headerlink" href="#how-do-i-make-an-executable-from-a-python-script" title="永久链接至标题">¶</a></h2>
|
||||
<p>请参看 <a class="reference external" href="https://cx-freeze.readthedocs.io/en/latest/">cx_Freeze</a> 和 <a class="reference external" href="http://www.py2exe.org/">py2exe</a>,两者都是允许你基于 Python 代码创建控制台和 GUI 可执行程序的 distutils 扩展。</p>
|
||||
</section>
|
||||
<section id="is-a-pyd-file-the-same-as-a-dll">
|
||||
<h2><a class="toc-backref" href="#id7"><code class="docutils literal notranslate"><span class="pre">*.pyd</span></code> 文件和 DLL 文件相同吗?</a><a class="headerlink" href="#is-a-pyd-file-the-same-as-a-dll" title="永久链接至标题">¶</a></h2>
|
||||
<p>是的, .pyd 文件也是 dll ,但有一些差异。如果你有一个名为 <code class="docutils literal notranslate"><span class="pre">foo.pyd</span></code> 的DLL,那么它必须有一个函数 <code class="docutils literal notranslate"><span class="pre">PyInit_foo()</span></code> 。 然后你可以编写 Python 代码 “import foo” ,Python 将搜索 foo.pyd (以及 foo.py 、 foo.pyc )。如果找到它,将尝试调用 <code class="docutils literal notranslate"><span class="pre">PyInit_foo()</span></code> 来初始化它。你不应将 .exe 与 foo.lib 链接,因为这会导致 Windows 要求存在 DLL 。</p>
|
||||
<p>请注意, foo.pyd 的搜索路径是 PYTHONPATH ,与 Windows 用于搜索 foo.dll 的路径不同。此外, foo.pyd 不需要存在来运行你的程序,而如果你将程序与 dll 链接,则需要 dll 。 当然,如果你想 <code class="docutils literal notranslate"><span class="pre">import</span> <span class="pre">foo</span></code> ,则需要 foo.pyd 。在 DLL 中,链接在源代码中用 <code class="docutils literal notranslate"><span class="pre">__declspec(dllexport)</span></code> 声明。 在 .pyd 中,链接在可用函数列表中定义。</p>
|
||||
</section>
|
||||
<section id="how-can-i-embed-python-into-a-windows-application">
|
||||
<h2><a class="toc-backref" href="#id8">我怎样将 Python 嵌入一个 Windows 程序?</a><a class="headerlink" href="#how-can-i-embed-python-into-a-windows-application" title="永久链接至标题">¶</a></h2>
|
||||
<p>在 Windows 应用程序中嵌入 Python 解释器可以总结如下:</p>
|
||||
<ol class="arabic">
|
||||
<li><p>请 _不要_ 直接在你的 .exe 文件中内置 Python 。在 Windows 上, Python 必须是一个 DLL ,这样才可以处理导入的本身就是 DLL 的模块。(这是第一个未记录的关键事实。)相反,链接到 <code class="file docutils literal notranslate"><span class="pre">python</span><em><span class="pre">NN</span></em><span class="pre">.dll</span></code> ;它通常安装在 <code class="docutils literal notranslate"><span class="pre">C:\Windows\System</span></code> 中。 <em>NN</em> 是 Python 版本,如数字“33”代表 Python 3.3 。</p>
|
||||
<p>你可以通过两种不同的方式链接到 Python 。加载时链接意味着链接到 <code class="file docutils literal notranslate"><span class="pre">python</span><em><span class="pre">NN</span></em><span class="pre">.lib</span></code> ,而运行时链接意味着链接 <code class="file docutils literal notranslate"><span class="pre">python</span><em><span class="pre">NN</span></em><span class="pre">.dll</span></code> 。(一般说明: <code class="file docutils literal notranslate"><span class="pre">python</span> <em><span class="pre">NN</span></em><span class="pre">.lib</span></code> 是所谓的“import lib”,对应于 <code class="file docutils literal notranslate"><span class="pre">python</span><em><span class="pre">NN</span></em><span class="pre">.dll</span></code> 。它只定义了链接器的符号。)</p>
|
||||
<p>运行时链接极大地简化了链接选项,一切都在运行时发生。你的代码必须使用 Windows 的 <code class="docutils literal notranslate"><span class="pre">LoadLibraryEx()</span></code> 程序加载 <code class="file docutils literal notranslate"><span class="pre">python</span><em><span class="pre">NN</span></em><span class="pre">.dll</span></code> 。代码还必须使用使用 Windows 的 <code class="docutils literal notranslate"><span class="pre">GetProcAddress()</span></code> 例程获得的指针访问 <code class="file docutils literal notranslate"><span class="pre">python</span><em><span class="pre">NN</span></em><span class="pre">.dll</span></code> 中程序和数据(即 Python 的 C API )。宏可以使这些指针对任何调用 Python C API 中的例程的 C 代码都是透明的。</p>
|
||||
<p>Borland 提示:首先使用 Coff2Omf.exe 将 <code class="file docutils literal notranslate"><span class="pre">python</span><em><span class="pre">NN</span></em><span class="pre">.lib</span></code> 转换为 OMF 格式。</p>
|
||||
</li>
|
||||
<li><p>如果你使用 SWIG ,很容易创建一个 Python “扩展模块”,它将使应用程序的数据和方法可供 Python 使用。SWIG将为你处理所有蹩脚的细节。结果是你将链接到 .exe 文件 <em>中</em> 的C代码 (!) 你不必创建 DLL 文件,这也简化了链接。</p></li>
|
||||
<li><p>SWIG 将创建一个 init 函数(一个 C 函数),其名称取决于扩展模块的名称。例如,如果模块的名称是 leo ,则 init 函数将被称为 initleo() 。 如果您使用 SWIG 阴影类,则 init 函数将被称为 initleoc() 。这初始化了一个由阴影类使用的隐藏辅助类。</p>
|
||||
<p>你可以将步骤 2 中的 C 代码链接到 .exe 文件的原因是调用初始化函数等同于将模块导入 Python ! (这是第二个关键的未记载事实。)</p>
|
||||
</li>
|
||||
<li><p>简而言之,你可以用以下代码使用扩展模块初始化 Python 解释器。</p>
|
||||
<div class="highlight-c notranslate"><div class="highlight"><pre><span></span><span class="cp">#include</span><span class="w"> </span><span class="cpf">"python.h"</span>
|
||||
<span class="p">...</span>
|
||||
<span class="n">Py_Initialize</span><span class="p">();</span><span class="w"> </span><span class="c1">// Initialize Python.</span>
|
||||
<span class="n">initmyAppc</span><span class="p">();</span><span class="w"> </span><span class="c1">// Initialize (import) the helper class.</span>
|
||||
<span class="n">PyRun_SimpleString</span><span class="p">(</span><span class="s">"import myApp"</span><span class="p">);</span><span class="w"> </span><span class="c1">// Import the shadow class.</span>
|
||||
</pre></div>
|
||||
</div>
|
||||
</li>
|
||||
<li><p>Python C API 存在两个问题,如果你使用除 MSVC 之外的编译器用于构建 python.dll ,这将会变得明显。</p>
|
||||
<p>问题1:采用 FILE* 参数的所谓“极高级”函数在多编译器环境中不起作用,因为每个编译器的FILE结构体概念都不同。从实现的角度来看,这些是非常 _低_ 级的功能。</p>
|
||||
<p>问题2:在为 void 函数生成包装器时,SWIG 会生成以下代码:</p>
|
||||
<div class="highlight-c notranslate"><div class="highlight"><pre><span></span><span class="n">Py_INCREF</span><span class="p">(</span><span class="n">Py_None</span><span class="p">);</span>
|
||||
<span class="n">_resultobj</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">Py_None</span><span class="p">;</span>
|
||||
<span class="k">return</span><span class="w"> </span><span class="n">_resultobj</span><span class="p">;</span>
|
||||
</pre></div>
|
||||
</div>
|
||||
<p>Py_None 是一个宏,它扩展为对 pythonNN.dll 中名为 _Py_NoneStruct 的复杂数据结构的引用。同样,此代码将在多编译器环境中失败。将此类代码替换为:</p>
|
||||
<div class="highlight-c notranslate"><div class="highlight"><pre><span></span><span class="k">return</span><span class="w"> </span><span class="n">Py_BuildValue</span><span class="p">(</span><span class="s">""</span><span class="p">);</span>
|
||||
</pre></div>
|
||||
</div>
|
||||
<p>有可能使用 SWIG 的 <code class="docutils literal notranslate"><span class="pre">%typemap</span></code> 命令自动进行更改,但我无法使其工作(我是一个完全的SWIG新手)。</p>
|
||||
</li>
|
||||
<li><p>使用 Python shell 脚本从 Windows 应用程序内部建立 Python 解释器窗口并不是一个好主意;生成的窗口将独立于应用程序的窗口系统。相反,你(或 wxPythonWindow 类)应该创建一个“本机”解释器窗口。将该窗口连接到Python解释器很容易。你可以将 Python的 i/o 重定向到支持读写的 _任意_ 对象,因此你只需要一个包含 read() 和 write() 方法的 Python 对象(在扩展模块中定义)。</p></li>
|
||||
</ol>
|
||||
</section>
|
||||
<section id="how-do-i-keep-editors-from-inserting-tabs-into-my-python-source">
|
||||
<h2><a class="toc-backref" href="#id9">如何让编辑器不要在我的 Python 源代码中插入 tab ?</a><a class="headerlink" href="#how-do-i-keep-editors-from-inserting-tabs-into-my-python-source" title="永久链接至标题">¶</a></h2>
|
||||
<p>本 FAQ 不建议使用制表符, Python 样式指南 <span class="target" id="index-2"></span><a class="pep reference external" href="https://www.python.org/dev/peps/pep-0008"><strong>PEP 8</strong></a> ,为发行的 Python 代码推荐 4 个空格;这也是 Emacs python-mode 默认值。</p>
|
||||
<p>在任何编辑器下,混合制表符和空格都是一个坏主意。 MSVC 在这方面没有什么不同,并且很容易配置为使用空格: 点击 <span class="menuselection">Tools ‣ Options ‣ Tabs</span>,对于文件类型“Default”,设置“Tab size”和“Indent size”为 4 ,并选择“插入空格”单选按钮。</p>
|
||||
<p>如果混合制表符和空格导致前导空格出现问题, Python 会引发 <a class="reference internal" href="../library/exceptions.html#IndentationError" title="IndentationError"><code class="xref py py-exc docutils literal notranslate"><span class="pre">IndentationError</span></code></a> 或 <a class="reference internal" href="../library/exceptions.html#TabError" title="TabError"><code class="xref py py-exc docutils literal notranslate"><span class="pre">TabError</span></code></a> 。你还可以运行 <a class="reference internal" href="../library/tabnanny.html#module-tabnanny" title="tabnanny: Tool for detecting white space related problems in Python source files in a directory tree."><code class="xref py py-mod docutils literal notranslate"><span class="pre">tabnanny</span></code></a> 模块以批处理模式检查目录树。</p>
|
||||
</section>
|
||||
<section id="how-do-i-check-for-a-keypress-without-blocking">
|
||||
<h2><a class="toc-backref" href="#id10">如何在不阻塞的情况下检查按键?</a><a class="headerlink" href="#how-do-i-check-for-a-keypress-without-blocking" title="永久链接至标题">¶</a></h2>
|
||||
<p>使用 <a class="reference internal" href="../library/msvcrt.html#module-msvcrt" title="msvcrt: Miscellaneous useful routines from the MS VC++ runtime. (Windows)"><code class="xref py py-mod docutils literal notranslate"><span class="pre">msvcrt</span></code></a> 模块。 这是一个标准的 Windows 专属扩展模块。 它定义了一个函数 <code class="docutils literal notranslate"><span class="pre">kbhit()</span></code> 用于检查是否有键盘中的某个键被按下,以及 <code class="docutils literal notranslate"><span class="pre">getch()</span></code> 用于获取一个字符而不将其回显。</p>
|
||||
</section>
|
||||
</section>
|
||||
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="sphinxsidebar" role="navigation" aria-label="main navigation">
|
||||
<div class="sphinxsidebarwrapper">
|
||||
<h3><a href="../contents.html">目录</a></h3>
|
||||
<ul>
|
||||
<li><a class="reference internal" href="#">Python在Windows上的常见问题</a><ul>
|
||||
<li><a class="reference internal" href="#how-do-i-run-a-python-program-under-windows">我怎样在Windows下运行一个Python程序?</a></li>
|
||||
<li><a class="reference internal" href="#how-do-i-make-python-scripts-executable">我怎么让 Python 脚本可执行?</a></li>
|
||||
<li><a class="reference internal" href="#why-does-python-sometimes-take-so-long-to-start">为什么有时候 Python 程序会启动缓慢?</a></li>
|
||||
<li><a class="reference internal" href="#how-do-i-make-an-executable-from-a-python-script">我怎样使用 Python 脚本制作可执行文件?</a></li>
|
||||
<li><a class="reference internal" href="#is-a-pyd-file-the-same-as-a-dll"><code class="docutils literal notranslate"><span class="pre">*.pyd</span></code> 文件和 DLL 文件相同吗?</a></li>
|
||||
<li><a class="reference internal" href="#how-can-i-embed-python-into-a-windows-application">我怎样将 Python 嵌入一个 Windows 程序?</a></li>
|
||||
<li><a class="reference internal" href="#how-do-i-keep-editors-from-inserting-tabs-into-my-python-source">如何让编辑器不要在我的 Python 源代码中插入 tab ?</a></li>
|
||||
<li><a class="reference internal" href="#how-do-i-check-for-a-keypress-without-blocking">如何在不阻塞的情况下检查按键?</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<h4>上一个主题</h4>
|
||||
<p class="topless"><a href="extending.html"
|
||||
title="上一章">扩展/嵌入常见问题</a></p>
|
||||
<h4>下一个主题</h4>
|
||||
<p class="topless"><a href="gui.html"
|
||||
title="下一章">图形用户界面(GUI)常见问题</a></p>
|
||||
<div role="note" aria-label="source link">
|
||||
<h3>本页</h3>
|
||||
<ul class="this-page-menu">
|
||||
<li><a href="../bugs.html">报告 Bug</a></li>
|
||||
<li>
|
||||
<a href="https://github.com/python/cpython/blob/3.8/Doc/faq/windows.rst"
|
||||
rel="nofollow">显示源代码
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="clearer"></div>
|
||||
</div>
|
||||
<div class="related" role="navigation" aria-label="related navigation">
|
||||
<h3>导航</h3>
|
||||
<ul>
|
||||
<li class="right" style="margin-right: 10px">
|
||||
<a href="../genindex.html" title="总目录"
|
||||
>索引</a></li>
|
||||
<li class="right" >
|
||||
<a href="../py-modindex.html" title="Python 模块索引"
|
||||
>模块</a> |</li>
|
||||
<li class="right" >
|
||||
<a href="gui.html" title="图形用户界面(GUI)常见问题"
|
||||
>下一页</a> |</li>
|
||||
<li class="right" >
|
||||
<a href="extending.html" title="扩展/嵌入常见问题"
|
||||
>上一页</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.8.20 Documentation</a> »
|
||||
</li>
|
||||
|
||||
<li class="nav-item nav-item-1"><a href="index.html" >Python 常见问题</a> »</li>
|
||||
<li class="right">
|
||||
|
||||
|
||||
<div class="inline-search" role="search">
|
||||
<form class="inline-search" action="../search.html" method="get">
|
||||
<input placeholder="快速搜索" aria-label="快速搜索" type="text" name="q" />
|
||||
<input type="submit" value="转向" />
|
||||
<input type="hidden" name="check_keywords" value="yes" />
|
||||
<input type="hidden" name="area" value="default" />
|
||||
</form>
|
||||
</div>
|
||||
|
|
||||
</li>
|
||||
|
||||
</ul>
|
||||
</div>
|
||||
<div class="footer">
|
||||
© <a href="../copyright.html">版权所有</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 />
|
||||
|
||||
<br />
|
||||
|
||||
The Python Software Foundation is a non-profit corporation.
|
||||
<a href="https://www.python.org/psf/donations/">Please donate.</a>
|
||||
<br />
|
||||
<br />
|
||||
|
||||
最后更新于 12月 09, 2024.
|
||||
<a href="https://docs.python.org/3/bugs.html">Found a bug</a>?
|
||||
<br />
|
||||
|
||||
Created using <a href="https://www.sphinx-doc.org/">Sphinx</a> 2.4.4.
|
||||
</div>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
Reference in New Issue
Block a user