<?xml version="1.0" encoding="UTF-8"?>
<rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/"
    xmlns:atom="http://www.w3.org/2005/Atom" xmlns:media="http://search.yahoo.com/mrss/" version="2.0">
    <channel>
        
        <title>
            <![CDATA[ 熊治杰 - freeCodeCamp.org ]]>
        </title>
        <description>
            <![CDATA[ freeCodeCamp 是一个免费学习编程的开发者社区，涵盖 Python、HTML、CSS、React、Vue、BootStrap、JSON 教程等，还有活跃的技术论坛和丰富的社区活动，在你学习编程和找工作时为你提供建议和帮助。 ]]>
        </description>
        <link>https://www.freecodecamp.org/chinese/news/</link>
        <image>
            <url>https://cdn.freecodecamp.org/universal/favicons/favicon.png</url>
            <title>
                <![CDATA[ 熊治杰 - freeCodeCamp.org ]]>
            </title>
            <link>https://www.freecodecamp.org/chinese/news/</link>
        </image>
        <generator>Eleventy</generator>
        <lastBuildDate>Mon, 11 May 2026 15:33:02 +0000</lastBuildDate>
        <atom:link href="https://www.freecodecamp.org/chinese/news/author/xiong/rss.xml" rel="self" type="application/rss+xml" />
        <ttl>60</ttl>
        
            <item>
                <title>
                    <![CDATA[ Python 读取 JSON 文件——如何从一个文件中读取 JSON 数据并解析转存 ]]>
                </title>
                <description>
                    <![CDATA[ 欢迎！如果你想学习如何在Python中和JSON文件交互，那么本文适合你。 你将学习：  * 为什么JSON格式如此重要  * JSON的基本结构和数据类型  * JSON和字典如何在Python中协同工作  * 如何使用Python内置的json模块  * 如何将JSON字符串转换为Python对象，反之亦然  * 如何使用loads()和dumps()  * 如何让JSON字符串自动缩进  * 如何在Python中使用load()读取JSON文件  * 如何在Python中使用dump()将JSON字符串写入文件  * 以及更多 准备好了吗？让我们开始吧！✨ 🔹 介绍：什么是JSON JSON格式的产生最初是受到JavaScript（一种用于Web开发的编程语言）语法的启发，但在那之后，它成为一种独立于语言的数据格式 ，并且今天我们所使用的大多数编程语言都可以生成和读取JSON。 JSON的重要性和使用例子 基本上，JSON是一种用于存储或表示数据的格式。它的常见用例包括Web开发和配置文件。 让我们看看原因：  * Web开发：  在Web应用程序中，通常用J ]]>
                </description>
                <link>https://www.freecodecamp.org/chinese/news/python-read-json-file-how-to-load-json-from-a-file-and-parse-dumps/</link>
                <guid isPermaLink="false">63569539509503074debe724</guid>
                
                    <category>
                        <![CDATA[ Python ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ 熊治杰 ]]>
                </dc:creator>
                <pubDate>Mon, 24 Oct 2022 03:30:00 +0000</pubDate>
                <media:content url="https://chinese.freecodecamp.org/news/content/images/2022/10/Read-JSON-image.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p data-test-label="translation-intro">
        <strong>原文：</strong> <a href="https://www.freecodecamp.org/news/python-read-json-file-how-to-load-json-from-a-file-and-parse-dumps/" target="_blank" rel="noopener noreferrer" data-test-label="original-article-link">Python Read JSON File – How to Load JSON from a File and Parse Dumps</a>
      </p><!--kg-card-begin: markdown--><p>欢迎！如果你想学习如何在Python中和JSON文件交互，那么本文适合你。</p>
<p><strong>你将学习：</strong></p>
<ul>
<li>为什么JSON格式如此重要</li>
<li>JSON的基本结构和数据类型</li>
<li>JSON和字典如何在Python中协同工作</li>
<li>如何使用Python内置的<code>json</code>模块</li>
<li>如何将JSON字符串转换为Python对象，反之亦然</li>
<li>如何使用<code>loads()</code>和<code>dumps()</code></li>
<li>如何让JSON字符串自动缩进</li>
<li>如何在Python中使用<code>load()</code>读取JSON文件</li>
<li>如何在Python中使用<code>dump()</code>将JSON字符串写入文件</li>
<li>以及更多</li>
</ul>
<p>准备好了吗？让我们开始吧！✨</p>
<h2 id="json">🔹 介绍：什么是JSON</h2>
<p><img src="https://www.freecodecamp.org/news/content/images/2020/10/image-98.png" alt="image-98" width="600" height="400" loading="lazy"></p>
<p>JSON格式的产生最初是受到JavaScript（一种用于Web开发的编程语言）语法的启发，但在那之后，它成为一种<strong>独立于语言的数据格式</strong>，并且今天我们所使用的大多数编程语言都可以生成和读取JSON。</p>
<h3 id="json">JSON的重要性和使用例子</h3>
<p>基本上，JSON是一种用于存储或表示数据的格式。它的常见用例包括Web开发和配置文件。</p>
<p>让我们看看原因：</p>
<ul>
<li><strong>Web开发：</strong> 在Web应用程序中，通常用JSON从服务端向客户端发送数据，反之亦然。</li>
</ul>
<p><img src="https://www.freecodecamp.org/news/content/images/2020/10/image-65.png" alt="image-65" width="600" height="400" loading="lazy"></p>
<ul>
<li><strong>配置文件：</strong> JSON还用于存储配置和设置信息。例如，要创建<a href="https://developer.chrome.com/apps/first_app#one">Google Chrome App</a>，则需要一个名为<code>manifest.json</code>的JSON文件，用于指定应用程序的名称、描述、当前版本以及其它属性和设置。</li>
</ul>
<p><img src="https://www.freecodecamp.org/news/content/images/2020/10/image-99.png" alt="image-99" width="600" height="400" loading="lazy"></p>
<h2 id="json">🔸 JSON的结构和格式</h2>
<p>既然已经知道了JSON的用途，那么让我们通过一个比萨饼订单数据的示例来看看它的基本结构：</p>
<pre><code class="language-JSON">{ 
	"size": "medium",
	"price": 15.67,
	"toppings": ["mushrooms", "pepperoni", "basil"],
	"extra_cheese": false,
	"delivery": true,
	"client": {
		"name": "Jane Doe",
		"phone": null,
		"email": "janedoe@email.com"
	}
}
</code></pre>
<p>上面是示例的sample.json文件</p>
<p>以下是JSON格式的主要特征：</p>
<ul>
<li>有一系列用花括号<code>{}</code>括起来的键-值对。</li>
<li>每个键都使用以下格式映射到特定值：</li>
</ul>
<pre><code>"key": &lt;value&gt; 
</code></pre>
<p>💡 <strong>提示：</strong><code>value</code>的内容必须用双引号括起来。</p>
<ul>
<li>键-值对用逗号分隔，只有最后一对后面可以不加逗号。</li>
</ul>
<pre><code class="language-JSON">{
	"size": "medium", # Comma!
	"price": 15.67
}
</code></pre>
<p>💡 <strong>提示：</strong> 我们通常使用不同级别的缩进来格式化JSON，以使数据更易于阅读。在本文中，你将学习如何使用Python自动添加缩进。</p>
<h3 id="json">JSON数据类型：键和值</h3>
<p>JSON文件具有特定规则，其用于确定哪些数据类型是有效的键和值。</p>
<ul>
<li><strong>键</strong>必须是字符串。</li>
<li><strong>值</strong>可以是字符串、数字、数组、布尔值（<code>true</code>/<code>false</code>）、<code>null</code>或JSON对象。</li>
</ul>
<p>根据<a href="https://docs.python.org/3/library/json.html#json.dumps">Python文档</a>：</p>
<blockquote>
<p>JSON的键/值对中的键始终是<a href="https://docs.python.org/3/library/stdtypes.html#str"><code>str</code>类型</a>。当字典转换为JSON时，字典中的所有键都被强制转换为字符串。</p>
</blockquote>
<h3 id="">风格指南</h3>
<p>根据<a href="https://google.github.io/styleguide/jsoncstyleguide.xml">Google JSON Style Guide</a>：</p>
<ul>
<li>始终使用有意义的名称。</li>
<li>数组类型的值对应的键名应使用复数形式，所有其它键名应为单数形式。例如：如果对应的值是数组，请使用<code>orders</code>而不是<code>order</code>。</li>
<li>JSON数据中不应该有注释。</li>
</ul>
<h2 id="jsonvspythondictionaries">🔹 JSON vs. Python Dictionaries（字典数据类型）</h2>
<p>JSON和字典从显示形式来看可能非常相似，但它们有很大的不同。让我们看看它们是如何“连接（译者：这里意思应该是它们之间的关系）”，以及如何相互补充，来使得Python成为处理JSON文件的强大工具。</p>
<p>JSON是用于表示和存储数据的文件格式，而Python字典是Pythons程序运行时保存在内存中的实际数据结构（对象）。</p>
<h3 id="jsonpython">JSON和Python字典如何协同工作</h3>
<p><img src="https://www.freecodecamp.org/news/content/images/2020/10/image-100.png" alt="image-100" width="600" height="400" loading="lazy"></p>
<p>当我们在Python中处理JSON文件时，我们不能直接读取数据并在程序中使用它，这是因为整个文件被表示为单个字符串，我们无法单独访问键值对。</p>
<p>除非······</p>
<p>我们使用JSON文件的键-值对创建一个Python字典，这样我们就可以在程序中使用它来读取、使用和修改（如果需要的话）数据。</p>
<p>这是JSON和Python字典之间的“联系”：JSON是数据的字符串表示，字典是程序运行时在内存中创建的实际数据结构。（译者注：字典转换为JSON叫序列化，反之为反序列化）</p>
<p>很好，既然你已经对JSON有足够多的了解，那么让我们开始深入了解实际情况中如何在Python里使用JSON的。</p>
<h2 id="json">🔸 JSON模块</h2>
<p>幸运的是，Python自带一个名为<code>json</code>的内置模块，安装Python时会自动安装该模块，这个模块包含一些帮助处理JSON文件和字符串的功能。</p>
<p>我们将在接下来的示例中使用此模块。</p>
<h3 id="json">如何导入JSON模块</h3>
<p>要在程序中使用<code>json</code>，只需在文件顶部写一个导入语句。（译者注：实际上只要在使用它之前导入就行）</p>
<p>就像这样：</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2020/10/image-73.png" alt="image-73" width="600" height="400" loading="lazy"></p>
<p>通过此行就可以使用模块中定义的函数，我们将在示例中调用其中几个方法。</p>
<p><strong>💡 提示：</strong> 如果写了上面的导入语句，则需要使用下面的语法来调用在<code>json</code>模块中定义的函数：</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2020/10/image-76.png" alt="image-76" width="600" height="400" loading="lazy"></p>
<h2 id="pythonjson">🔹 Python和JSON字符串</h2>
<p>为了说明<code>json</code>模块中最重要的一些函数是如何工作的，我们将使用JSON格式的多行字符串。</p>
<h3 id="json">JSON字符串</h3>
<p>特别地，这个字符串只是一个普通的遵循JSON格式的多行Python字符串，我们将在示例中使用它。</p>
<pre><code class="language-python">data_JSON =  """
{
	"size": "Medium",
	"price": 15.67,
	"toppings": ["Mushrooms", "Extra Cheese", "Pepperoni", "Basil"],
	"client": {
		"name": "Jane Doe",
		"phone": "455-344-234",
		"email": "janedoe@email.com"
	}
}
"""
</code></pre>
<p>JSON字符串</p>
<ul>
<li>我们使用三重引号在Python中定义多行字符串。</li>
<li>然后我们将字符串赋给变量<code>data_JSON</code>。</li>
</ul>
<p>💡 <strong>提示：</strong><a href="https://www.python.org/dev/peps/pep-0008/#string-quotes">Python Style Guide</a>建议三重引号字符串使用双引号。</p>
<h3 id="jsonpython">JSON字符串到Python字典</h3>
<p>我们将使用此JSON格式的字符串来创建一个可以访问、使用和修改的Python字典。</p>
<p>为此，我们将使用<code>json</code>模块的<code>loads()</code>函数，并将字符串作为参数传递进去。</p>
<p>这是基本语法：</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2020/10/image-77.png" alt="image-77" width="600" height="400" loading="lazy"></p>
<p>这是代码：</p>
<pre><code class="language-python"># 导入模块
import json

# JSON格式的字符串
data_JSON =  """
{
	"size": "Medium",
	"price": 15.67,
	"toppings": ["Mushrooms", "Extra Cheese", "Pepperoni", "Basil"],
	"client": {
		"name": "Jane Doe",
		"phone": "455-344-234",
		"email": "janedoe@email.com"
	}
}
"""

# 将JSON字符串转换为字典
data_dict = json.loads(data_JSON)
</code></pre>
<p>注意这行：</p>
<pre><code class="language-python">data_dict = json.loads(data_JSON)
</code></pre>
<ul>
<li><code>json.loads(data_json)</code>使用JSON字符串的键-值对创建一个新字典，并返回这个字典。</li>
<li>然后返回的字典被赋值给变量<code>data_dict</code>。</li>
</ul>
<p><strong>太棒了！</strong> 如果我们打印这个字典，会看到以下输出：</p>
<pre><code class="language-python">{'size': 'Medium', 'price': 15.67, 'toppings': ['Mushrooms', 'Extra Cheese', 'Pepperoni', 'Basil'], 'client': {'name': 'Jane Doe', 'phone': '455-344-234', 'email': 'janedoe@email.com'}}
</code></pre>
<p>字典中已填充了JSON字符串的数据，每个键值对都被成功添加到字典里。</p>
<p>现在让我们尝试使用与访问常规Python字典相同的语法，来访问键-值对的值，看看会发生什么：</p>
<pre><code class="language-python">print(data_dict["size"])
print(data_dict["price"])
print(data_dict["toppings"])
print(data_dict["client"])
</code></pre>
<p>输出是：</p>
<pre><code>Medium
15.67
['Mushrooms', 'Extra Cheese', 'Pepperoni', 'Basil']
{'name': 'Jane Doe', 'phone': '455-344-234', 'email': 'janedoe@email.com'}
</code></pre>
<p>每个键都可以用来访问其对应的值，正如我们所期望的那样。</p>
<p>💡 <strong>提示：</strong> 我们可以像使用任何其它Python字典一样来使用此字典。例如，我们可以调用字典的方法，添加、更新和删除键-值对，以及其它等等操作，我们甚至可以在for循环中使用它。</p>
<h3 id="jsonpython">JSON到Python：类型转换</h3>
<p>当使用<code>loads()</code>从JSON字符串来创建Python字典时，你会注意到一些值将被转换为Python中对应的值和数据类型。</p>
<p><a href="https://docs.python.org/3/library/json.html#encoders-and-decoders">Python文档</a>上的这个<code>json</code>模块表格总结了JSON数据类型和Python数据类型的对应关系：</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2020/10/image-79.png" alt="image-79" width="600" height="400" loading="lazy"></p>
<p>这是官方<a href="https://docs.python.org/3/library/json.html#encoders-and-decoders">json模块文档</a>中的表格</p>
<p>**💡 提示：**当我们处理JSON文件时，转换表同样也适用。</p>
<h3 id="pythonjson">Python字典到JSON字符串</h3>
<p>现在你知道了如何用JSON格式的字符串创建Python字典。</p>
<p>但有时我们可能需要做相反的事情，即用对象（例如字典）创建JSON格式的字符串，以便打印、显示、存储，或者将其作为字符串使用。</p>
<p>为此，我们可以使用<code>json</code>模块的<code>dumps</code>函数，该函数要求将（要转换的）对象作为参数传递：</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2020/10/image-80.png" alt="image-80" width="600" height="400" loading="lazy"></p>
<p><strong>💡 提示：</strong> 此函数将返回一个字符串。</p>
<p>这是一个例子，我们将Python字典<code>client</code>转换为JSON格式的字符串，并将其赋值给变量：</p>
<pre><code class="language-python"># Python Dictionary
client = {
    "name": "Nora",
    "age": 56,
    "id": "45355",
    "eye_color": "green",
    "wears_glasses": False
}

# 获得一个JSON格式的字符串
client_JSON = json.dumps(client)
</code></pre>
<p>注意这行：</p>
<pre><code class="language-python">client_JSON = json.dumps(client)
</code></pre>
<ul>
<li><code>json.dumps(client)</code>创建并返回一个包含字典中所有键-值对的JSON格式的字符串。</li>
<li>然后将此字符串赋值给<code>client_JSON</code>变量。</li>
</ul>
<p>如果我们打印这个字符串，会看到如下输出：</p>
<pre><code class="language-python">{"name": "Nora", "age": 56, "id": "45355", "eye_color": "green", "wears_glasses": false}
</code></pre>
<p>💡 <strong>提示：</strong> 请注意，最后一个值（<code>false</code>）已更改。在Python字典中，此值为<code>False</code>，但在JSON中等效值为<code>false</code>，这有助于我们确认原始字典现在确实已经表示为JSON格式的字符串。</p>
<p>如果我们检查此变量（<code>client_JSON</code>）的数据类型，我们会看到：</p>
<pre><code class="language-python">&lt;class 'str'&gt;
</code></pre>
<p>所以这个函数的返回值确实是一个字符串。</p>
<h3 id="pythonjson">Python到JSON：类型转换</h3>
<p>当我们将字典转换为JSON字符串时，也会发生类型转换过程。来自<a href="https://docs.python.org/3/library/json.html#json.JSONEncoder">Python文档</a>的这张表显示了二者相对应的值：</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2020/10/image-81.png" alt="image-81" width="600" height="400" loading="lazy"></p>
<p>表格来自<a href="https://docs.python.org/3/library/json.html#json.JSONEncoder">官方json模块文档</a>。</p>
<h3 id="json">如何使用缩进打印JSON数据</h3>
<p>如果我们使用<code>dumps</code>函数打印上一示例中得到的字符串，我们会看到：</p>
<pre><code class="language-python">{"name": "Nora", "age": 56, "id": "45355", "eye_color": "green", "wears_glasses": false}
</code></pre>
<p>但是这样可读性不是很高，对吧？</p>
<p>我们可以通过添加<strong>缩进</strong>来提高JSON字符串的可读性。</p>
<p>我们只需传递第二个参数来指定要用于JSON字符串缩进的空格数，（<code>dumps</code>函数）就会自动执行此操作：</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2020/10/image-111.png" alt="image-111" width="600" height="400" loading="lazy"></p>
<p><strong>💡 提示：</strong> 第二个参数必须是非负整数（表示空格数）或字符串，如果<code>indent</code>是一个字符串（例如<code>"\t"</code>），则用该字符串缩进每个级别（<a href="https://docs.python.org/3/library/json.html#json.dump">帮助文档</a>).</p>
<p>现在，如果我们使用第二个参数来调用<code>dumps</code>：</p>
<pre><code class="language-python">client_JSON = json.dumps(client, indent=4)
</code></pre>
<p>打印<code>client_JSON</code>的结果是：</p>
<pre><code class="language-python">{
    "name": "Nora",
    "age": 56,
    "id": "45355",
    "eye_color": "green",
    "wears_glasses": false
}
</code></pre>
<p>这很棒，对吧？现在我们的字符串格式很好看，这对我们处理存储人类可读格式的数据的文件来说将非常有用。</p>
<h3 id="">如何对键排序</h3>
<p>如果有需要，还可以按字母顺序对键进行排序，只需写入参数<code>sort_keys</code>并传递值<code>True</code>：</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2020/10/image-84.png" alt="image-84" width="600" height="400" loading="lazy"></p>
<p>💡 <strong>提示：</strong> 如果不传递值，<code>sort_keys</code>默认为<code>False</code>。</p>
<p>例如：</p>
<pre><code class="language-python">client_JSON = json.dumps(client, sort_keys=True)
</code></pre>
<p>将会返回键按字母顺序排序的JSON字符串：</p>
<pre><code class="language-python">{"age": 56, "eye_color": "green", "id": "45355", "name": "Nora", "wears_glasses": false}
</code></pre>
<h3 id="">如何同时按字母排序和使用缩进</h3>
<p>要生成（键）按字母顺序和有缩进的JSON字符串，只需要传递两个参数：</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2020/10/image-104.png" alt="image-104" width="600" height="400" loading="lazy"></p>
<p>在这个例子中，输出是：</p>
<pre><code class="language-python">{
    "age": 56,
    "eye_color": "green",
    "id": "45355",
    "name": "Nora",
    "wears_glasses": false
}
</code></pre>
<p><strong>💡 提示：</strong> 可以按任何顺序（相对于彼此）传递这两个参数，但（要进行转换的）对象必须是第一个参数。</p>
<p>太棒了，现在你已经知道如何使用JSON字符串，那就让我们看看如何在Python程序中处理JSON文件。</p>
<h2 id="json">🔸 JSON和文件</h2>
<p>JSON通常用于将数据存储在文件中，因此Python为我们提供了在程序中读取这些类型的文件、处理文件的数据以及编写新数据所需的工具。</p>
<p>**💡 提示：**JSON文件有一个<code>.json</code>扩展名：</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2020/10/image-62.png" alt="image-62" width="600" height="400" loading="lazy"></p>
<p>来看看如何在Python中处理<code>.json</code>文件。</p>
<h3 id="pythonjson">在Python中如何读取JSON文件</h3>
<p>假设我们创建了一个 <code>orders.json</code> 文件，文件中有披萨店两个订单的数据：</p>
<pre><code class="language-python">{
	"orders": [ 
		{
			"size": "medium",
			"price": 15.67,
			"toppings": ["mushrooms", "pepperoni", "basil"],
			"extra_cheese": false,
			"delivery": true,
			"client": {
				"name": "Jane Doe",
				"phone": null,
				"email": "janedoe@email.com"
			}
		},
		{
			"size": "small",
			"price": 6.54,
			"toppings": null,
			"extra_cheese": true,
			"delivery": false,
			"client": {
				"name": "Foo Jones",
				"phone": "556-342-452",
				"email": null
			}
		}
	]
}
</code></pre>
<p>orders.json</p>
<p>请花点时间分析此JSON文件的结构。</p>
<p>以下是一些提示：</p>
<ul>
<li>请注意值的数据类型、缩进和文件的整体结构。</li>
<li>主键<code>"orders"</code>的值是一个JSON对象数组（这个数组在Python中表示列表），（数组里）每个JSON对象都保存了披萨订单的数据。</li>
</ul>
<p>如果我们想在Python中读取此文件，只需要使用<code>with</code>语句：</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2020/10/image-87.png" alt="image-87" width="600" height="400" loading="lazy"></p>
<p>💡 <strong>提示：</strong> 在上面的语法中，我们可以为<code>file</code>（绿色框）指定任何名称，这是一个我们可以在<code>with</code>语句中用来引用文件对象的变量。</p>
<p>此语法中的关键代码行是：</p>
<pre><code>data = json.load(file)
</code></pre>
<ul>
<li><code>json.load（file）</code>创建并返回一个新的包含JSON文件中键-值对的Python字典。</li>
<li>然后将该字典赋值给<code>data</code>变量。</li>
</ul>
<p>💡 <strong>提示：</strong> 请注意，我们使用的是<code>load()</code>而不是<code>loads()</code>，这是<code>json</code>模块中的不同函数。你将在本文的末尾了解更多它们的差异。</p>
<p>一旦我们将JSON文件的内容作为字典存储在<code>data</code>变量中，我们就可以使用它做想要做的任何事情。</p>
<h3 id="">例子</h3>
<p>例如，如果我们执行：</p>
<pre><code class="language-python">print(len(data["orders"]))
</code></pre>
<p>输出为<code>2</code>，因为主键<code>orders</code>的值是一个包含两个元素的列表。</p>
<p>我们还可以使用键访问其对应的值，即处理JSON文件时通常要做的事情。</p>
<p>例如，要访问第一个订单的toppings，我们执行：</p>
<pre><code>data["orders"][0]["toppings"]
</code></pre>
<ul>
<li>首先，我们选择主键<code>"orders"</code></li>
<li>然后，我们选择列表中的第一个元素（索引<code>0</code>）</li>
<li>最后，我们选择与键<code>"toppings"</code>对应的值</li>
</ul>
<p>你可以在图表中以图形方式看到此“路径”：</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2020/10/image-101.png" alt="image-101" width="600" height="400" loading="lazy"></p>
<p>如果我们打印这个值，输出是：</p>
<pre><code class="language-python">['mushrooms', 'pepperoni', 'basil']
</code></pre>
<p>这正是我们所期望的。你只需要通过使用必要的键和索引来“深入”了解字典的结构（可以使用原始JSON文件或字符串作为视觉参考），就可以访问、修改或删除任何值。</p>
<p><strong>💡 提示：</strong> 请记住，我们正在使用新创建的字典，对此字典所做的更改不会影响原JSON文件。要更新文件的内容，需要写入文件中。</p>
<h3 id="json">如何写一个JSON文件</h3>
<p>让我们看看如何写一个JSON文件。</p>
<p>第一行的<code>with</code>语句（和读JSON文件）非常相似，唯一的改变是需要以<code>'w'</code>（即写入）模式打开文件，这样才能修改文件。</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2020/10/image-105.png" alt="image-105" width="600" height="400" loading="lazy"></p>
<p><strong>💡 提示：</strong> 如果当前工作目录（文件夹）中文件不存在，则会自动创建该文件。如果文件存在，通过使用<code>'w'</code>模式，我们将替换文件的全部内容。</p>
<p>在<code>with</code>语句中，有两种写入JSON文件的方法：</p>
<ul>
<li><code>dump</code></li>
<li><code>dumps</code></li>
</ul>
<p>让我们详细看看。</p>
<p><strong>第一种方法：<code>dump</code></strong></p>
<p>这是一个有两个参数的函数：</p>
<ul>
<li>将以JSON格式存储的对象（例如字典）。</li>
<li>将存储该JSON字符串的文件（即文件对象）。</li>
</ul>
<p><img src="https://www.freecodecamp.org/news/content/images/2020/10/image-91.png" alt="image-91" width="600" height="400" loading="lazy"></p>
<p>如果披萨店想从JSON文件中删除客户的数据，并创建一个新版本的<code>orders_new.json</code>文件。</p>
<p>我们可以通过以下代码完成此操作：</p>
<pre><code class="language-python"># 打开orders.json文件
with open("orders.json") as file:
    # 加载它的内容并创建一个新字典
    data = json.load(file)

    # 在每个order中删除"client"键-值对
    for order in data["orders"]:
        del order["client"]

# 打开（或者创建）一个orders_new.json文件
# 保存新版本的数据
with open("orders_new.json", 'w') as file:
    json.dump(data, file)
</code></pre>
<p>这是 <code>orders.json</code> 中数据的原始版本，请注意里面存在<code>"client"</code>键-值对。</p>
<pre><code class="language-python">{
	"orders": [ 
		{
			"size": "medium",
			"price": 15.67,
			"toppings": ["mushrooms", "pepperoni", "basil"],
			"extra_cheese": false,
			"delivery": true,
			"client": {
				"name": "Jane Doe",
				"phone": null,
				"email": "janedoe@email.com"
			}
		},
		{
			"size": "small",
			"price": 6.54,
			"toppings": null,
			"extra_cheese": true,
			"delivery": false,
			"client": {
				"name": "Foo Jones",
				"phone": "556-342-452",
				"email": null
			}
		}
	]
}
</code></pre>
<p>orders.json</p>
<p>这是<code>orders_new.json</code>文件里的新版本数据：</p>
<pre><code class="language-Python">{"orders": [{"size": "medium", "price": 15.67, "toppings": ["mushrooms", "pepperoni", "basil"], "extra_cheese": false, "delivery": true}, {"size": "small", "price": 6.54, "toppings": null, "extra_cheese": true, "delivery": false}]}
</code></pre>
<p>orders_new.json</p>
<p>如果仔细分析，你会发现<code>"clients"</code>键-值对从所有订单中被删除。</p>
<p>然而，这个文件中缺少了一些东西，对吗？</p>
<p>请花点时间思考一下…可能是什么？</p>
<p>当然是缩进！</p>
<p>该文件实际上看起来不像JSON文件，但我们可以通过将参数<code>indentation=4</code>传递给<code>dump()</code>来轻松解决这个问题。</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2020/10/image-92.png" alt="image-92" width="600" height="400" loading="lazy"></p>
<p>现在文件内容如下所示：</p>
<pre><code class="language-python">{
    "orders": [
        {
            "size": "medium",
            "price": 15.67,
            "toppings": [
                "mushrooms",
                "pepperoni",
                "basil"
            ],
            "extra_cheese": false,
            "delivery": true
        },
        {
            "size": "small",
            "price": 6.54,
            "toppings": null,
            "extra_cheese": true,
            "delivery": false
        }
    ]
}
</code></pre>
<p>orders_new.json</p>
<p>多么大的变化啊！这正是我们期望的JSON文件的样子。</p>
<p>现在你已经知道如何使用<code>load()</code>和<code>dump</code>来读取和写入JSON文件，就让我们看看这两个函数和用来处理JSON字符串的函数之间的区别。</p>
<h2 id="loadvsloads">🔹 load() vs. loads()</h2>
<p>这个表格总结了这两个函数之间的主要区别：</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2020/10/image-110.png" alt="image-110" width="600" height="400" loading="lazy"></p>
<p>💡 <strong>提示：</strong> 将<code>loads()</code>视为"load string"，这有助于记住函数处理的目标。</p>
<h2 id="dumpvsdumps">🔸 dump() vs. dumps()</h2>
<p>这是一个总结了两个函数之间主要差异的表格：</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2020/10/image-109.png" alt="image-109" width="600" height="400" loading="lazy"></p>
<p>💡 <strong>提示：</strong> 将<code>dumps()</code>视为"dump string"，这有助于记住函数处理的目标。</p>
<h2 id="json">🔹 JSON中的重要术语</h2>
<p>最后，使用JSON需要了解两个重要术语：</p>
<ul>
<li><strong>序列化：</strong> 将一个对象转换为JSON字符串</li>
<li><strong>反序列化：</strong> 将一个JSON字符串转换为对象</li>
</ul>
<h2 id="">🔸 总结</h2>
<ul>
<li>JSON（JavaScript Object Notation）是一种用于表示和存储的数据格式。</li>
<li>它通常用于存储配置信息和在网络上传输数据。</li>
<li>JSON文件有一个<code>.json</code>扩展名。</li>
<li>可以将JSON字符串转换为Python对象，反之亦然。</li>
<li>可以读取JSON文件并用其键-值对创建Python对象。</li>
<li>可以以JSON格式存储Python对象的内容，并将其写入JSON文件。</li>
</ul>
<p>我真的希望你喜欢我的文章，并觉得它很有帮助。现在你已经知道如何在Python中使用JSON了。在Twitter上可以关注我<a href="https://twitter.com/EstefaniaCassN">@EstefaniaCassN</a>和<a href="https://www.udemy.com/user/estefania-cn/">查看我的在线课程</a>。</p>
<!--kg-card-end: markdown--> ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ Python 编程手册 ]]>
                </title>
                <description>
                    <![CDATA[ 这本Python编程手册遵循“80/20定律”：使用20%的时间学习80%的内容。 我认为这种方法可以为学习者提供一个对Python全面的了解。 本手册并没有涵盖与Python相关的全部内容。它专注于这门编程语言的核心主题，并且试图简化那些复杂的内容。 我希望这本手册可以帮助您实现：学习Python的基础 > Note: 您可以获取这本手册的PDF、ePub或者Mobi版本 [https://flaviocopes.com/page/python-handbook/] Enjoy it! 目录  * Python介绍  * 如何安装Python  * 如何运行Python程序  * Python 2 vs Python 3  * Python基础  * Python数据类型  * Python运算符  * Python三元运算符  * Python字符串  * Python布尔值  * Python数字  * ]]>
                </description>
                <link>https://www.freecodecamp.org/chinese/news/the-python-handbook/</link>
                <guid isPermaLink="false">6336ebf096409407bcba3417</guid>
                
                    <category>
                        <![CDATA[ Python ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ 熊治杰 ]]>
                </dc:creator>
                <pubDate>Fri, 30 Sep 2022 11:18:00 +0000</pubDate>
                <media:content url="https://chinese.freecodecamp.org/news/content/images/2022/09/book.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p data-test-label="translation-intro">
        <strong>原文：</strong> <a href="https://www.freecodecamp.org/news/the-python-handbook/" target="_blank" rel="noopener noreferrer" data-test-label="original-article-link">The Python Handbook – Learn Python for Beginners</a>
      </p><!--kg-card-begin: markdown--><p>这本Python编程手册遵循“80/20定律”：使用20%的时间学习80%的内容。</p>
<p>我认为这种方法可以为学习者提供一个对Python全面的了解。</p>
<p>本手册并没有涵盖与Python相关的全部内容。它专注于这门编程语言的核心主题，并且试图简化那些复杂的内容。</p>
<p>我希望这本手册可以帮助您实现：<strong>学习Python的基础</strong></p>
<blockquote>
<p>Note: 您可以获取这本手册的<a href="https://flaviocopes.com/page/python-handbook/">PDF、ePub或者Mobi版本</a></p>
</blockquote>
<p>Enjoy it!</p>
<h2 id="summary">目录</h2>
<ul>
<li><a href="#introduction-to-python">Python介绍</a></li>
<li><a href="#how-to-install-python">如何安装Python</a></li>
<li><a href="#how-to-run-python-programs">如何运行Python程序</a></li>
<li><a href="#python2-vs-python3">Python 2 vs Python 3</a></li>
<li><a href="#python-basics">Python基础</a></li>
<li><a href="#data-types-in-python">Python数据类型</a></li>
<li><a href="#operators">Python运算符</a></li>
<li><a href="#the-ternary-operator-in-python">Python三元运算符</a></li>
<li><a href="#strings-in-python">Python字符串</a></li>
<li><a href="#booleans-in-python">Python布尔值</a></li>
<li><a href="#numbers-in-python">Python数字</a></li>
<li><a href="#constants-in-python">Python常量</a></li>
<li><a href="#enums-in-python">Python枚举</a></li>
<li><a href="#user-input-in-python">Python用户输入</a></li>
<li><a href="#control-statements-in-python">Python控制语句</a></li>
<li><a href="#lists-in-python">Python列表</a></li>
<li><a href="#tuples-in-python">Python元组</a></li>
<li><a href="#dictionaries-in-python">Python字典</a></li>
<li><a href="#sets-in-python">Python集合</a></li>
<li><a href="#functions-in-python">Python函数</a></li>
<li><a href="#objects-in-python">Python对象</a></li>
<li><a href="#loops-in-python">Python循环</a></li>
<li><a href="#classes-in-python">Python类</a></li>
<li><a href="#modules-in-python">Python模块</a></li>
<li><a href="#the-python-standard-library">Python标准库</a></li>
<li><a href="#the-pep8-python-style-guide">Python PEP8风格指导</a></li>
<li><a href="#debugging-in-python">Python代码调试</a></li>
<li><a href="#variable-scope-in-python">Python变量作用域</a></li>
<li><a href="#how-to-accept-arguments-from-the-command-line-in-python">Python接收从命令行传入的参数</a></li>
<li><a href="#lambda-functions-in-python">Python的Lambda函数</a></li>
<li><a href="#recursion-in-python">Python递归</a></li>
<li><a href="#nested-functions-in-python">Python嵌套函数</a></li>
<li><a href="#closures-in-python">Python闭包</a></li>
<li><a href="#decorators-in-python">Python装饰器</a></li>
<li><a href="#docstrings-in-python">Python文档字符串</a></li>
<li><a href="#introspection-in-python">Python反射</a></li>
<li><a href="#annotations-in-python">Python注解</a></li>
<li><a href="#exceptions-in-python">Python异常</a></li>
<li><a href="#the-with-statement-in-python">Python中with语句</a></li>
<li><a href="#how-to-install-3rd-party-packages-in-python-using-pip">Python如何使用pip安装第三方包</a></li>
<li><a href="#list-comprehensions-in-python">Python列表推导式</a></li>
<li><a href="#polymorphism-in-python">Python多态</a></li>
<li><a href="#operator-overloading-in-python">Python运算符重载</a></li>
<li><a href="#virtual-environments-in-python">Python虚拟环境</a></li>
<li><a href="#conclusion">总结</a></li>
</ul>
<h2 id="introduction-to-python">Python介绍</h2>
<p>Python正在逐步“占领”编程世界。它的受欢迎度和使用度正在以计算机历史中前所未有的方式实现增长。</p>
<p>Python在各种应用场景下都表现出色——<strong>Shell 脚本</strong>、<strong>自动化的任务</strong>和<strong>Web 开发</strong>只是其基本的应用。</p>
<p>Python是做<strong>数据分析</strong>和<strong>机器学习</strong>的首选语言，但是它也可以用来创建游戏或者在嵌入式设备上工作。</p>
<p>最重要的是，Python是世界上多所大学介绍<strong>计算机科学课程</strong>时选择的编程语言。</p>
<p>许多学生选择Python作为自己的第一门编程语言来学习。很多人正在学习Python，将来还会有更多人学习它。并且对于学习者中的大部分人来说，Python将是他们唯一需要的编程语言。</p>
<p>基于其独特的情况，Python在未来很有可能会更快地发展。</p>
<p>Python这门编程语言的特点是简单易上手、可读性强、非常直接、易于理解。</p>
<p>Python的生态系统非常庞大，可能需要一个图书馆才能容纳你所想象到的一切。</p>
<p>因为其直观的语法、庞大的社区和充满活力的生态系统，Python是一门适合编程初学者的高级编程语言。</p>
<p>Python也受到不同领域的专家赞赏。</p>
<p>从技术上讲，Python是一种解释型语言，它不像编译型语言（例如C或Java）那样具有中间编译阶段。</p>
<p>和许多解释型语言一样，Python是动态类型的，这意味着您不必声明所使用的变量的类型，并且变量不必为特定类型。</p>
<p>这有利有弊。特别是，您编写程序的速度会更快，但另一方面，您从工具中获得防止出现可能错误的帮助会较少。这意味着您只有在执行程序时才能发现某些问题。</p>
<p>Python支持多种编程范式，包括面向过程编程、面向对象编程和函数式编程。它足够灵活，可以适应不同的需求。</p>
<p>自从Python由Guido van Rossum于1991年创建后，它便越来越受欢迎——尤其是在过去5年中，正如这张Google趋势信息图所示：</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2021/03/Screen-Shot-2020-11-09-at-19.22.38.png" alt="Screen-Shot-2020-11-09-at-19.22.38" width="600" height="400" loading="lazy"></p>
<p>开始Python编程非常容易。您只需从<a href="https://www.python.org/">python.org</a>选择适用于Windows、macOS或Linux的官方软件包安装，然后就可以开始使用Python了。</p>
<p>如果您是编程新手，我将会在接下来的内容中引导您从零开始成为一名Python程序员。</p>
<p>即使您目前是一名专门研究另一种编程语言的程序员，Python也值得您了解，因为我认为它只会继续发展壮大。</p>
<p>像C++和Rust这样相对于Python来说更“低级”的语言，对于专业程序员来说可能很棒，但是初学者如果从这两门语言开始学习编程，会感到畏惧，而且需要很长时间才能掌握。</p>
<p>另一方面，Python是一种适用于任何人——学生、使用Excel完成日常工作的人、科学家等等——的编程语言。</p>
<p><strong>这是每个对编程感兴趣的人都应该首先学习的语言</strong>。</p>
<h2 id="how-to-install-python"> 如何安装Python </h2>
<p>进入<a href="https://www.python.org">https://www.python.org</a> ，选择下载菜单（Downloads），然后选择您的操作系统，将出现一个带有官方软件包下载链接的面板：</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2021/03/Screen-Shot-2020-11-09-at-13.57.36-1.png" alt="Screen-Shot-2020-11-09-at-13.57.36-1" width="600" height="400" loading="lazy"></p>
<p>请确保遵循关于您电脑所用的操作系统的特定说明。如果是在macOS上安装，您可以在<a href="https://flaviocopes.com/python-installation-macos/">https://flaviocopes.com/python-installation-macos/</a> 上找到详细指南。</p>
<h2 id="how-to-run-python-programs">如何运行Python程序</h2>
<p>您可以使用几种不同的方式来运行Python程序。</p>
<p>特别地，使用交互式环境（输入Python代码后，便立即执行它），和将Python程序保存到文件中，然后再执行它，这二者之间存在区别。</p>
<p>让我们从交互式环境开始。</p>
<p>如果您打开终端并输入<code>python</code>，将在终端窗口上看到如下内容：</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2021/03/Screen-Shot-2020-11-10-at-13.44.07.png" alt="Screen-Shot-2020-11-10-at-13.44.07" width="600" height="400" loading="lazy"></p>
<p>这是Python REPL（交互式解释器，即读取-评估-打印-循环）。</p>
<p>注意<code>&gt;&gt;&gt;</code>符号和之后的光标。，您可以在此处输入任何Python代码，然后按 <code>enter</code> 键运行它。</p>
<p>例如尝试定义一个新变量</p>
<pre><code class="language-python">name = "Flavio"
</code></pre>
<p>然后使用<code>print()</code>打印<code>name</code>的值：</p>
<pre><code class="language-python">print(name)
</code></pre>
<p><img src="https://www.freecodecamp.org/news/content/images/2021/03/Screen-Shot-2020-11-10-at-14.11.57.png" alt="Screen-Shot-2020-11-10-at-14.11.57" width="600" height="400" loading="lazy"></p>
<blockquote>
<p>请注意：在REPL中，您也可以只输入<code>name</code>，然后按 <code>enter</code> 键，您会看到<code>name</code>的值。但是在写到文件中的程序里，如果这样做，您将看不到任何输出——您需要使用 <code>print()</code> 代替这种写法。</p>
</blockquote>
<p>您在此处编写的任何Python代码行都将立即执行。</p>
<p>输入<code>quit()</code>可以退出这个Python REPL。</p>
<p>您可以使用Python自动安装的IDLE应用程序使用相同的交互式环境：</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2021/03/Screen-Shot-2020-11-10-at-14.13.25.png" alt="Screen-Shot-2020-11-10-at-14.13.25" width="600" height="400" loading="lazy"></p>
<p>这对您来说可能更方便，因为与使用终端相比，使用鼠标可以更轻松地四处移动和复制/粘贴。</p>
<p>以上是Python默认附带的基础内容。不过我建议您安装<a href="https://ipython.org/">IPython</a>，它可能是您能找到的最好的Python命令行REPL应用程序。</p>
<p>使用下面的命令安装它</p>
<pre><code class="language-sh">pip install ipython
</code></pre>
<p>上面的命令需要确保pip可执行文件的路径在您的环境变量中，安装好之后运行<code>ipython</code>：</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2021/03/Screen-Shot-2020-11-11-at-09.36.29.png" alt="Screen-Shot-2020-11-11-at-09.36.29" width="600" height="400" loading="lazy"></p>
<p><code>ipython</code>是另一个让您使用Python REPL的接口，并提供了一些不错的功能，如语法高亮、代码补全等等。</p>
<p>运行Python程序的第二种方法是将Python程序代码写入文件，例如<code>program.py</code>：</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2021/03/Screen-Shot-2020-11-10-at-14.01.24.png" alt="Screen-Shot-2020-11-10-at-14.01.24" width="600" height="400" loading="lazy"></p>
<p>然后用<code>python program.py</code>运行它：</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2021/03/Screen-Shot-2020-11-10-at-14.01.32.png" alt="Screen-Shot-2020-11-10-at-14.01.32" width="600" height="400" loading="lazy"></p>
<blockquote>
<p>请注意，我们约定使用<code>.py</code>扩展名保存Python程序文件。</p>
</blockquote>
<p>在这种情况下，程序作为一个整体被执行，而不是一次运行一行。而这就是我们运行程序的典型方式。</p>
<p>我们使用REPL进行快速的代码原型设计和学习。</p>
<p>在Linux和macOS上，也可以将Python程序文件转换为shell脚本，方法是在文件最前面加上一个特殊行，用来指示使用哪个可执行文件来运行它。</p>
<p>在我的系统上，Python解释器的路径是<code>/usr/bin/python3</code>，所以我在第一行输入<code>#!/usr/bin/python3</code>：</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2021/03/Screen-Shot-2020-11-10-at-14.17.26.png" alt="Screen-Shot-2020-11-10-at-14.17.26" width="600" height="400" loading="lazy"></p>
<p>然后我可以对文件设置执行权限：</p>
<pre><code class="language-sh">chmod u+x program.py
</code></pre>
<p>然后我可以使用下面的命令运行程序</p>
<pre><code class="language-sh">./program.py
</code></pre>
<p><img src="https://www.freecodecamp.org/news/content/images/2021/03/Screen-Shot-2020-11-10-at-14.18.42.png" alt="Screen-Shot-2020-11-10-at-14.18.42" width="600" height="400" loading="lazy"></p>
<p>这在您编写与终端交互的脚本时特别有用。</p>
<p>我们还有许多其它方式可以运行Python程序。</p>
<p>一种方法是使用VS Code，尤其是Microsoft官方的Python扩展插件：</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2021/03/Screen-Shot-2020-11-10-at-14.23.32.png" alt="Screen-Shot-2020-11-10-at-14.23.32" width="600" height="400" loading="lazy"></p>
<p>安装好此扩展插件后，您将可以使用Python代码自动补全、语法错误检查、自动格式化和使用<code>pylint</code>进行代码检查，以及一些特殊命令，包括：</p>
<p><strong>Python: Start REPL</strong>  用于在VS Code的集成终端中运行REPL：</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2021/03/Screen-Shot-2020-11-10-at-14.31.36.png" alt="Screen-Shot-2020-11-10-at-14.31.36" width="600" height="400" loading="lazy"></p>
<p><strong>Python: Run Python File in Terminal</strong>  用于在终端中运行当前文件：</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2021/03/Screen-Shot-2020-11-10-at-14.31.06.png" alt="Screen-Shot-2020-11-10-at-14.31.06" width="600" height="400" loading="lazy"></p>
<p><strong>Python: Run Current File in Python Interactive Window</strong> 在 Python 交互窗口中运行当前文件：</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2021/03/Screen-Shot-2020-11-10-at-14.30.02-1.png" alt="Screen-Shot-2020-11-10-at-14.30.02-1" width="600" height="400" loading="lazy"></p>
<p>以及很多其它命令。只需打开命令面板（查看 -&gt; 命令面板，或按下Cmd+Shift+P）并输入<code>python</code>，即可查看所有与Python相关的命令：</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2021/03/Screen-Shot-2020-11-10-at-14.30.02.png" alt="Screen-Shot-2020-11-10-at-14.30.02" width="600" height="400" loading="lazy"></p>
<p>另一种轻松运行Python代码的方法是repl.it，这是一个非常不错的网站，它提供了一个编程环境，您可以使用任何语言创建并运行程序，包括Python：</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2021/03/Screen-Shot-2020-11-10-at-14.33.58.png" alt="Screen-Shot-2020-11-10-at-14.33.58" width="600" height="400" loading="lazy"></p>
<p>使用这个网站要先注册（免费注册），然后在“create a repl”下单击Python：</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2021/03/Screen-Shot-2020-11-10-at-14.46.34.png" alt="Screen-Shot-2020-11-10-at-14.46.34" width="600" height="400" loading="lazy"></p>
<p>然后您将看到一个带有<code>main.py</code>文件的编辑器，这样就已经准备好了编写Python代码：</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2021/03/Screen-Shot-2020-11-10-at-14.47.15.png" alt="Screen-Shot-2020-11-10-at-14.47.15" width="600" height="400" loading="lazy"></p>
<p>一旦您写好一些代码后，单击“Run”就可以在窗口右侧运行它：</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2021/03/Screen-Shot-2020-11-10-at-14.48.09.png" alt="Screen-Shot-2020-11-10-at-14.48.09" width="600" height="400" loading="lazy"></p>
<p>我认为repl.it很方便，因为：</p>
<ul>
<li>您只需分享链接即可轻松分享代码</li>
<li>它允许多人处理相同的代码</li>
<li>它可以托管长时间运行的程序</li>
<li>您可以在上面安装第三方包</li>
<li>它为您提供用于复杂应用程序的键值数据库</li>
</ul>
<h2 id="python2-vs-python3">Python 2 vs Python 3</h2>
<p>我们一开始就应该讨论的一个关键主题是Python 2与Python 3。</p>
<p>Python 3于2008年被推出，其后作为主要的Python版本一直在被持续开发，而Python 2则通过错误修复和安全补丁进行维护，直到2020年初。</p>
<p>在那一天，对Python 2的支持停止。</p>
<p>许多程序仍然使用Python 2编写，并且组织仍在积极致力于这些程序，因为迁移到Python 3并非易事，升级这些程序需要大量工作。并且重要文件的大型迁移总是会引入新的bug。</p>
<p>但是对应新的代码程序，除非您必须遵守组织设置的强制使用Python 2的规则，否则应使用Python 3进行编写。</p>
<blockquote>
<p>本书重点介绍 Python 3。</p>
</blockquote>
<h2 id="python-basics">Python 基础</h2>
<h3 id="python">Python中的变量</h3>
<p>我们可以通过使用赋值运算符<code>=</code>为“标签”赋值，从而创建一个新的Python变量。</p>
<p>在下面这个示例中，我们将字符串<code>"Roger"</code>分配给变量<code>name</code>：</p>
<pre><code class="language-python">name = "Roger"
</code></pre>
<p>下面是一个给变量<code>age</code>赋值为数字的示例：</p>
<pre><code class="language-python">age = 8
</code></pre>
<p>一个变量的名字可以由字符、数字和<code>_</code>下划线字符组成。变量名不能以数字开头。以下都是<strong>有效的</strong>变量名：</p>
<pre><code class="language-python">name1
AGE
aGE
a11111
my_name
_name
</code></pre>
<p>以下都是<strong>无效的</strong>变量名：</p>
<pre><code class="language-python">123
test!
name%
</code></pre>
<p>除此之外，任何输入都是有效的变量名，除非它是Python的<strong>关键字</strong>，如<code>for</code>、<code>if</code>、<code>while</code>、<code>import</code>等就是关键字。</p>
<p>无需记住它们，因为如果您使用其中任何一个关键字作为变量名，Python都会提醒您，并且您会逐渐视它们为Python语法的一部分。</p>
<h3 id="python">Python表达式和语句</h3>
<p>我们可以_构造_任意一个有返回值的表达式代码，例如</p>
<pre><code class="language-python">1 + 1
"Roger"
</code></pre>
<p>另一方面，语句是对值的操作。例如，下面是2个语句：</p>
<pre><code class="language-python">name = "Roger"
print(name)
</code></pre>
<p>程序由一系列语句组成。每个语句占一行，但您可以使用分号在一行中包含多个语句：</p>
<pre><code class="language-python">name = "Roger"; print(name)
</code></pre>
<h3 id="">注释</h3>
<p>在Python程序中，井号之后的所有内容都被忽略，并被视为注释：</p>
<pre><code class="language-python">#this is a commented line

name = "Roger"  # this is an inline comment
</code></pre>
<h3 id="python">Python中的缩进</h3>
<p>Python中的缩进是有意义的。</p>
<p>您不能像这样随意缩进：</p>
<pre><code class="language-python">name = "Flavio"
    print(name)
</code></pre>
<p>对于其它一些语言，空格是没有意义的，但是在Python中，缩进很重要。</p>
<p>在上面这种情况下，如果您尝试运行这个程序，您会得到一个<code>IndentationError: unexpected indent</code>错误，因为缩进有特殊的含义。</p>
<p>一个缩进中的所有内容属于一个块，如控制语句块或条件块，函数或类主体。 我们稍后会看到更多关于这些内容的解释。</p>
<h2 id="data-types-in-python">Python数据类型</h2>
<p>Python有几种内置类型。</p>
<p>如果您创建<code>name</code>变量并为其分配值"Roger"，则此变量现在自动表示<strong>String</strong>数据类型。</p>
<pre><code class="language-python">name = "Roger"
</code></pre>
<p>您可以使用<code>type()</code>函数检查变量的类型，即将变量作为参数，然后将函数返回结果与<code>str</code>进行比较：</p>
<pre><code class="language-python">name = "Roger"
type(name) == str  # True
</code></pre>
<p>或者使用<code>isinstance()</code>：</p>
<pre><code class="language-python">name = "Roger"
isinstance(name, str)  # True
</code></pre>
<blockquote>
<p>请注意，要在REPL之外查看<code>True</code>值，您需要将此代码包装在<code>print()</code>中，但为了清楚起见，我避免使用它。</p>
</blockquote>
<p>我们在这里使用了<code>str</code>，但这种方法同样适用于其它数据类型。</p>
<p>首先，我们有数字。整数使用<code>int</code>表示，浮点数（分数）的类型为<code>float</code>：</p>
<pre><code class="language-python">age = 1
type(age) == int  # True
</code></pre>
<pre><code class="language-python">fraction = 0.1
type(fraction) == float  # True
</code></pre>
<p>您已经了解了如何从字面值创建某一类型的变量，如下所示：</p>
<pre><code class="language-python">name = "Flavio"
age = 20
</code></pre>
<p>Python自动从变量值检测数据类型。</p>
<p>您还可以通过向类构造器传递字面值或变量名，来创建特定类型的变量：</p>
<pre><code class="language-python">name = str("Flavio")
anotherName = str(name)
</code></pre>
<p>您还可以使用类构造器，将一种类型转换为另一种类型。Python将尝试转换为正确的值，例如从字符串中提取数字：</p>
<pre><code class="language-python">age = int("20")
print(age)  # 20

fraction = 0.1
intFraction = int(fraction)
print(intFraction)  # 0
</code></pre>
<p>这称为<strong>casting</strong>。当然，这种转换并不总是有效，具体取决于传递的值。如果您在上面的字符串中写了<code>test</code>而不是<code>20</code>，您会得到一个<code>ValueError: invalid literal for int() with base 10: 'test'</code>错误。</p>
<p>这些只是基础的数据类型。Python中有更多其它数据类型：</p>
<ul>
<li><code>complex</code> 复数</li>
<li><code>bool</code> 布尔值</li>
<li><code>list</code> 列表</li>
<li><code>tuple</code> 元组</li>
<li><code>range</code> 范围</li>
<li><code>dict</code> 字典</li>
<li><code>set</code> 集合</li>
</ul>
<p>以及更多！</p>
<p>我们很快就会探索它们。</p>
<h2 id="operators">Python运算符</h2>
<p>我们使用Python运算符来对值和变量进行运算操作。</p>
<p>我们可以根据它们执行操作的类型来划分运算符：</p>
<ul>
<li>赋值运算符</li>
<li>算术运算符</li>
<li>比较运算符</li>
<li>逻辑运算符</li>
<li>位运算符</li>
</ul>
<p>再加上一些其它有趣的运算符，比如<code>is</code>和<code>in</code>。</p>
<h3 id="python">Python赋值运算符</h3>
<p>赋值运算符用于为变量赋值：</p>
<pre><code class="language-python">age = 8
</code></pre>
<p>或者将变量的值分配给另一个变量：</p>
<pre><code class="language-python">age = 8
anotherVariable = age
</code></pre>
<p>从Python 3.8开始，可以使用_海象运算符_<code>:=</code>为变量赋值，同时该运算可作为另一个操作的一部分。例如在<code>if</code>或循环的条件部分。这个稍后再谈。</p>
<h3 id="python">Python算术运算符</h3>
<p>Python有许多算术运算符：<code>+</code>、<code>-</code>、<code>*</code>、<code>/</code>（除法）、<code>%</code>（取余）、<code>**</code>（求幂）和 <code>//</code>（向下取整除法） ：</p>
<pre><code class="language-python">1 + 1  # 2
2 - 1  # 1
2 * 2  # 4
4 / 2  # 2
4 % 3  # 1
4 ** 2  # 16
4 // 2  # 2
</code></pre>
<blockquote>
<p>请注意，操作数之间不需要空格，但加上空格有利于可读性。</p>
</blockquote>
<p><code>-</code>也可用作一元运算符表示负号：</p>
<pre><code class="language-python">print(-4)  # -4
</code></pre>
<p><code>+</code>也可用于连接字符串：</p>
<pre><code class="language-python">"Roger" + " is a good dog"
# Roger is a good dog
</code></pre>
<p>我们可以将赋值运算符与算术运算符结合起来：</p>
<ul>
<li><code>+=</code></li>
<li><code>-=</code></li>
<li><code>*=</code></li>
<li><code>/=</code></li>
<li><code>%=</code></li>
<li>以及等等</li>
</ul>
<p>例子：</p>
<pre><code class="language-python">age = 8
age += 1
# age is now 9
</code></pre>
<h3 id="python">Python比较运算符</h3>
<p>Python定义了一些比较运算符：</p>
<ul>
<li><code>==</code></li>
<li><code>!=</code></li>
<li><code>&gt;</code></li>
<li><code>&lt;</code></li>
<li><code>&gt;=</code></li>
<li><code>&lt;=</code></li>
</ul>
<p>您可以使用这些运算符获取根据比较结果得到的布尔值（<code>True</code>或<code>False</code>）：</p>
<pre><code class="language-python">a = 1
b = 2

a == b  # False
a != b  # True
a &gt; b  # False
a &lt;= b  # True
</code></pre>
<h3 id="python">Python布尔运算符</h3>
<p>Python为我们提供了以下布尔运算符：</p>
<ul>
<li><code>not</code></li>
<li><code>and</code></li>
<li><code>or</code></li>
</ul>
<p>当使用<code>True</code>或<code>False</code>属性时，它们的作用类似于逻辑与、逻辑或和逻辑非，并且经常用于 <code>if</code> 条件表达式判断：</p>
<pre><code class="language-python">condition1 = True
condition2 = False

not condition1  # False
condition1 and condition2  # False
condition1 or condition2  # True
</code></pre>
<p>但是，请注意可能的混淆：</p>
<p>表达式中使用<code>or</code>，则表达式的结果是第一个为非假值（假值：<code>False</code>、<code>0</code>、<code>''</code>、<code>[]</code>..）的操作数，否则返回最后一个操作数作为表达式的值。</p>
<pre><code class="language-python">print(0 or 1)  # 1
print(False or 'hey')  # 'hey'
print('hi' or 'hey')  # 'hi'
print([] or False)  # 'False'
print(False or [])  # '[]'
</code></pre>
<p>Python文档将其（x or y）描述为<code>如果x为假，则为y，否则为x</code>。（译者：<code>or</code>碰到真值就停，没有真值就走到最后）</p>
<p><code>and</code>运算操作仅在第一个操作数为真时，才计算第二个操作数。因此，如果第一个操作数是假值（假值：<code>False</code>、<code>0</code>、<code>''</code>、<code>[]</code>..），它会返回那个操作数。否则，它就会计算第二个操作数：</p>
<pre><code class="language-python">print(0 and 1)  # 0
print(1 and 0)  # 0
print(False and 'hey')  # False
print('hi' and 'hey')  # 'hey'
print([] and False )  # []
print(False and [] )  # False
</code></pre>
<p>Python文档将其（x and y）描述为<code>如果x为假，则为x，否则为y</code>。（译者：<code>or</code>碰到假值就停，没有假值就走到最后）</p>
<h3 id="python">Python位运算符</h3>
<p>一些运算符用于处理位和二进制数：</p>
<ul>
<li><code>&amp;</code> 执行二进制与操作</li>
<li><code>|</code> 执行二进制或操作</li>
<li><code>^</code> 执行二进制异或操作</li>
<li><code>~</code> 执行二进制非操作</li>
<li><code>&lt;&lt;</code> 二进制左移操作</li>
<li><code>&gt;&gt;</code> 二进制右移操作</li>
</ul>
<p>一般很少使用位运算符，仅在非常特定的情况下使用，但是值得一提。</p>
<h3 id="pythonisin">Python中的<code>is</code>和<code>in</code></h3>
<p><code>is</code>被称为<strong>identity operator</strong>（验证运算符），用于比较两个对象，如果两者是同一个对象，则返回true。稍后将详细介绍对象。</p>
<p><code>in</code>被称为<strong>membership operator</strong>（成员运算符），用于判断一个值是否包含在一个列表或序列中。稍后将详细介绍列表和其他序列数据类型。</p>
<h2 id="the-ternary-operator-in-python">Python三元运算符</h2>
<p>使用Python三元运算符，您可以快速定义条件语句。</p>
<p>假设您有一个函数，它将<code>age</code>变量与<code>18</code>进行比较，并根据结果返回True或False。</p>
<p>可以不这样写：</p>
<pre><code class="language-python">def is_adult(age):
    if age &gt; 18:
        return True
    else:
        return False
</code></pre>
<p>您可以通过使用三元运算符这种方式来实现它：<br>
（译者：感觉这个例子不太好，因为这里写成<code>return age &gt; 18</code>会更好，换成这个例子<code>return "age大于18" if age &gt; 18 else "age小于等于18"</code>会更好理解一些）</p>
<pre><code class="language-python">def is_adult(age):
    return True if age &gt; 18 else False
</code></pre>
<p>首先定义条件为真的结果，然后判断条件，最后定义条件为假的结果：</p>
<pre><code class="language-python">&lt;条件为真得到的结果&gt; if &lt;条件表达式&gt; else &lt;条件为假得到的结果&gt;
</code></pre>
<h2 id="strings-in-python">Python字符串</h2>
<p>Python中的字符串是用单引号或双引号括起来的一串字符：</p>
<pre><code class="language-python">"Roger"
'Roger'
</code></pre>
<p>您可以将字符串赋值给变量：</p>
<pre><code class="language-python">name = "Roger"
</code></pre>
<p>您可以使用<code>+</code>运算符连接两个字符串：</p>
<pre><code class="language-python">phrase = "Roger" + " is a good dog"
</code></pre>
<p>您也可以使用<code>+=</code>将一个字符串添加到另一个字符串后面：</p>
<pre><code class="language-python">name = "Roger"
name += " is a good dog"

print(name)  # Roger is a good dog
</code></pre>
<p>您可以使用<code>str</code>类构造函数将数字转换为字符串：</p>
<pre><code class="language-python">str(8)  # "8"
</code></pre>
<p>这对于连接数字和字符串来说很重要：</p>
<pre><code class="language-python">print("Roger is " + str(8) + " years old")  # Roger is 8 years old
</code></pre>
<p>当使用特殊语法定义时，字符串可以是多行的，将字符串括在一组3个引号中：</p>
<pre><code class="language-python">print("""Roger is

    8

years old
""")

# double quotes, or single quotes

print('''
Roger is

    8

years old
''')
</code></pre>
<p>字符串具有一组内置方法，例如：</p>
<ul>
<li><code>isalpha()</code> 检查字符串是否只包含字母字符，并且不为空字符串</li>
<li><code>isalnum()</code> 检查字符串是否只包含字母字符或数字字符，并且不为空</li>
<li><code>isdecimal()</code> 检查字符串是否只包含十进制字符，并且不为空</li>
<li><code>lower()</code> 获取字符串的小写版本</li>
<li><code>islower()</code> 检查字符串是否全为小写</li>
<li><code>upper()</code> 获取字符串的大写版本</li>
<li><code>isupper()</code> 检查字符串是否全为大写</li>
<li><code>title()</code> 获取字符串的“标题化”版本（译者：所有单词首字母大写）</li>
<li><code>startsswith()</code> 检查字符串是否以特定子字符串开头</li>
<li><code>endswith()</code> 检查字符串是否以特定子字符串结尾</li>
<li><code>replace()</code> 替换字符串的一部分</li>
<li><code>split()</code> 按特定分隔符拆分字符串</li>
<li><code>strip()</code> 修剪字符串中的空格</li>
<li><code>join()</code> 将字符串添加到另一个字符串（译者：实际上是将字符串添加到另一个可迭代对象生成的字符串中）</li>
<li><code>find()</code> 查找特定子字符串在字符串中的位置</li>
</ul>
<p>以及其它等等。</p>
<p>这些方法都不会改变原始字符串，它们将会返回一个新的、修改后的字符串。例如：</p>
<pre><code class="language-python">name = "Roger"
print(name.lower())  # "roger"
print(name)  # "Roger"
</code></pre>
<p>您也可以使用一些全局函数来处理字符串。</p>
<p>这里我特别想到了<code>len()</code>，它返回给您指定字符串的长度：</p>
<pre><code class="language-python">name = "Roger"
print(len(name))  # 5
</code></pre>
<p><code>in</code>运算符可以让您检查字符串是否包含某个子字符串：</p>
<pre><code class="language-python">name = "Roger"
print("ger" in name)  # True
</code></pre>
<p>转义是一种将特殊字符添加到字符串中的方法。</p>
<p>例如，如何将双引号添加到被双引号包裹的字符串中？</p>
<pre><code class="language-python">name = "Roger"
</code></pre>
<p><code>"Ro"Ger"</code>将不起作用，因为Python会认为字符串以<code>"Ro"</code>结尾。</p>
<p>方法是使用<code>\</code>反斜杠字符转义字符串内的双引号：</p>
<pre><code class="language-python">name = "Ro\"ger"
</code></pre>
<p>这也适用于单引号<code>\'</code>，以及其它特殊格式字符，如制表符<code>\t</code>、换行符<code>\n</code>和反斜杠<code>\\</code>。</p>
<p>给定一个字符串，并给定一个索引（从0开始），您就可以使用方括号获取指定位置上的字符，从而获取特定内容：</p>
<pre><code class="language-python">name = "Roger"
name[0]  # 'R'
name[1]  # 'o'
name[2]  # 'g'
</code></pre>
<p>使用负数将从末尾开始计数：</p>
<pre><code class="language-python">name = "Roger"
name[-1]  # "r"
</code></pre>
<p>您还可以使用范围，即使用我们所说的<strong>切片</strong>：</p>
<pre><code class="language-python">name = "Roger"
name[0:2]  # "Ro"
name[:2]  # "Ro"
name[2:]  # "ger"
</code></pre>
<h2 id="booleans-in-python">Python布尔值</h2>
<p>Python提供了<code>bool</code>类型，它可以有两个值：<code>True</code> 和 <code>False</code>（首字母大写）。</p>
<pre><code class="language-python">done = False
done = True
</code></pre>
<p>布尔值对于条件控制结构特别有用，例如<code>if</code>语句：</p>
<pre><code class="language-python">done = True

if done:
    # run some code here
else:
    # run some other code
</code></pre>
<p>在判断值为<code>True</code>或<code>False</code>时，如果该值不是<code>bool</code>布尔类型，我们有一些取决于我们所检查值类型的规则：</p>
<ul>
<li>数字除<code>0</code>以外，始终为<code>True</code></li>
<li>字符串仅在是空字符串时为<code>False</code></li>
<li>列表、元组、集合和字典仅在其为空时为<code>False</code></li>
</ul>
<p>您可以通过以下方式检查值是否为布尔值：</p>
<pre><code class="language-python">done = True
type(done) == bool  # True
</code></pre>
<p>或者使用<code>isinstance()</code>，需要传递2个参数：变量和<code>bool</code>类：</p>
<pre><code class="language-python">done = True
isinstance(done, bool)  # True
</code></pre>
<p>全局函数<code>any()</code>在处理布尔值时也非常有用，当作为参数传递的可迭代对象（如列表）中的任意一个值是 <code>True</code>时，它就会返回 <code>True</code>（译者：类似<code>or</code>）：</p>
<pre><code class="language-python">book_1_read = True
book_2_read = False

read_any_book = any([book_1_read, book_2_read])  # True
</code></pre>
<p>全局函数<code>all()</code>相类似，但是是当传递给它的所有值都是<code>True</code>时，才返回 <code>True</code>（译者：类似<code>and</code>）：</p>
<pre><code class="language-python">ingredients_purchased = True
meal_cooked = False

ready_to_serve = all([ingredients_purchased, meal_cooked])  # False
</code></pre>
<h2 id="numbers-in-python">Python数字</h2>
<p>Python中的数字有3种类型：<code>int</code>、<code>float</code>和<code>complex</code>。</p>
<h3 id="python">Python整数</h3>
<p>整数使用<code>int</code>表示，您可以使用字面值定义整数：</p>
<pre><code class="language-python">age = 8
</code></pre>
<p>您还可以使用<code>int()</code>构造函数定义一个整数：</p>
<pre><code class="language-python">age = int(8)
</code></pre>
<p>您可以使用全局函数<code>type()</code>检查变量是否为<code>int</code>类型：</p>
<pre><code class="language-python">type(age) == int  # True
</code></pre>
<h3 id="python">Python浮点数</h3>
<p>浮点数（分数）的类型为<code>float</code>，您可以使用字面值定义浮点数：</p>
<pre><code class="language-python">fraction = 0.1
</code></pre>
<p>或者使用<code>float()</code>构造函数：</p>
<pre><code class="language-python">fraction = float(0.1)
</code></pre>
<p>您可以使用全局函数<code>type()</code>检查变量是否为<code>float</code>类型：</p>
<pre><code class="language-python">type(fraction) == float  # True
</code></pre>
<h3 id="python">Python复数</h3>
<p>复数属于<code>complex</code>类型。</p>
<p>您可以使用字面值定义它们：</p>
<pre><code class="language-python">complexNumber = 2+3j
</code></pre>
<p>或者使用<code>complex()</code>构造函数：</p>
<pre><code class="language-python">complexNumber = complex(2, 3)
</code></pre>
<p>一旦您定义了一个复数，您就可以得到它的实部和虚部：</p>
<pre><code class="language-python">complexNumber.real  # 2.0
complexNumber.imag  # 3.0
</code></pre>
<p>同样，您可以使用全局函数<code>type()</code>检查变量是否为<code>complex</code>类型：</p>
<pre><code class="language-python">type(complexNumber) == complex #True
</code></pre>
<h3 id="python">Python中数字的算术运算</h3>
<p>您可以使用算术运算符对数字执行算术运算：<code>+</code>、<code>-</code>、<code>*</code>、<code>/</code>（除法）、<code>%</code>（取余）、<code>**</code>（求幂）和<code>//</code>（向下取整除法）：</p>
<pre><code class="language-python">1 + 1  # 2
2 - 1  # 1
2 * 2  # 4
4 / 2  # 2
4 % 3  # 1
4 ** 2  # 16
4 // 2  # 2
</code></pre>
<p>您还可以使用复合赋值运算符</p>
<ul>
<li><code>+=</code></li>
<li><code>-=</code></li>
<li><code>*=</code></li>
<li><code>/=</code></li>
<li><code>%=</code></li>
<li>其它等等</li>
</ul>
<p>这样可以快速对变量执行运算操作：</p>
<pre><code class="language-python">age = 8
age += 1  # age: 9
</code></pre>
<h3 id="python">Python内置函数</h3>
<p>有2个内置函数可以帮助处理数字：</p>
<p><code>abs()</code>返回一个数字的绝对值。</p>
<p>给定一个数字，<code>round()</code>返回四舍五入到最接近整数的值：</p>
<pre><code class="language-python">round(0.12)  # 0
</code></pre>
<p>您可以指定第二个参数来设置舍入到小数点的精度：</p>
<pre><code class="language-python">round(0.12, 1)  # 0.1
</code></pre>
<p>Python标准库提供了其它几个数学实用函数和常量：</p>
<ul>
<li><code>math</code>包提供通用的数学函数和常量</li>
<li><code>cmath</code>包提供了处理复数的方法</li>
<li><code>decimal</code>包提供了处理小数和浮点数的方法</li>
<li><code>fractions</code>包提供了处理有理数的方法</li>
</ul>
<p>稍后我们将分别探讨其中的一些。</p>
<h2 id="constants-in-python">Python常量</h2>
<p>Python中无法强制改变的值是常量。</p>
<p>比较常用的是枚举：</p>
<pre><code class="language-Python">class Constants(Enum):
    WIDTH = 1024
    HEIGHT = 256
</code></pre>
<p>并使用<code>Constants.WIDTH.value</code>这样的表达获取每个值。</p>
<p>没有人可以重新分配该值。</p>
<p>否则，如果您想依赖命名约定（来定义常量），您可以遵守这个规则——声明大写的永远不应该改变的变量：</p>
<pre><code class="language-python">WIDTH = 1024
</code></pre>
<p>没有人会阻止您覆盖这个值，Python也不会阻止。（译者：全大写的变量表示不应改变的常量，这只是一种约定）</p>
<p>正如您将来会看到的，大多数Python代码都采用这种命名约定的写法。</p>
<h2 id="enums-in-python">Python枚举</h2>
<p>枚举是绑定到常量值的可读名称。</p>
<p>要使用枚举，请从<code>enum</code>标准库模块中导入<code>Enum</code>：</p>
<pre><code class="language-python">from enum import Enum
</code></pre>
<p>然后您可以用这种方式初始化一个新的枚举：</p>
<pre><code class="language-python">class State(Enum):
    INACTIVE = 0
    ACTIVE = 1
</code></pre>
<p>这样做后，您可以引用作为常量的<code>State.INACTIVE</code>和<code>State.ACTIVE</code>。</p>
<p>现在，如果您尝试打印<code>State.ACTIVE</code>，例如：</p>
<pre><code class="language-python">print(State.ACTIVE)
</code></pre>
<p>它不会返回<code>1</code>，而是返回<code>State.ACTIVE</code>。</p>
<p>枚举中分配的数字可以达到相同的效果：<code>print(State(1))</code>将打印<code>State.ACTIVE</code>。使用方括号符号<code>State['ACTIVE']</code>也是如此。</p>
<p>但是，您可以使用<code>State.ACTIVE.value</code>获取具体值。</p>
<p>您可以列出枚举的所有可能值：</p>
<pre><code class="language-python">list(State)  # [&lt;State.INACTIVE: 0&gt;, &lt;State.ACTIVE: 1&gt;]
</code></pre>
<p>您可以获取总数：</p>
<pre><code class="language-python">len(State)  # 2
</code></pre>
<h2 id="user-input-in-python">Python用户输入</h2>
<p>在Python命令行程序中，您可以使用<code>print()</code>函数向用户显示信息：</p>
<pre><code class="language-python">name = "Roger"
print(name)
</code></pre>
<p>我们也可以使用<code>input()</code>接受来自用户的输入：</p>
<pre><code class="language-python">print('What is your age?')
age = input()
print('Your age is ' + age)
</code></pre>
<p>这种方法在运行时获取输入，这意味着程序（执行到<code>input()</code>时）将停止执行，等待用户输入内容并按下<code>enter</code>键。</p>
<p>您还可以在程序调用时接受输入并进行更复杂的输入处理，稍后我们将看到如何做到这一点。</p>
<p>这适用于命令行程序。其它类型的应用程序需要使用不同的方式来接受输入。</p>
<h2 id="control-statements-in-python">Python控制语句</h2>
<p>当您处理布尔值和返回布尔值的表达式时，您可以根据它们的值为<code>True</code>或<code>False</code>来采取不同的方式。</p>
<p>在Python中，我们使用<code>if</code>语句来做到这一点：</p>
<pre><code class="language-python">condition = True

if condition == True:
    # do something
</code></pre>
<p>当条件解析为<code>True</code>时，就像上面的情况一样，if下面的代码块被执行。</p>
<p>什么是代码块？代码块是向右侧缩进一级（通常为4个空格）的部分：</p>
<pre><code class="language-python">condition = True

if condition == True:
    print("The condition")
    print("was true")
</code></pre>
<p>代码块可以由单行或多行组成，并在您移回到上一个缩进级别时结束：</p>
<pre><code class="language-python">condition = True

if condition == True:
    print("The condition")
    print("was true")

print("Outside of the if")
</code></pre>
<p>如果<code>if</code>的条件测试结果为<code>False</code>，结合<code>if</code>则可以执行<code>else</code>块：</p>
<pre><code class="language-python">condition = True

if condition == True:
    print("The condition")
    print("was True")
else:
    print("The condition")
    print("was False")
</code></pre>
<p>如果前面的<code>if</code>检查是<code>False</code>，您可以使用<code>elif</code>执行另一个条件检查：</p>
<pre><code class="language-python">condition = True
name = "Roger"

if condition == True:
    print("The condition")
    print("was True")
elif name == "Roger":
    print("Hello Roger")
else:
    print("The condition")
    print("was False")
</code></pre>
<p>如果<code>condition</code>为<code>False</code>并且<code>name</code>变量的值为"Roger"，则执行本例中的第二个代码块。</p>
<p>在一个<code>if</code>语句中，您只可以进行一次<code>if</code>和 <code>else</code>检查，但可以进行多个<code>elif</code>检查：</p>
<pre><code class="language-python">condition = True
name = "Roger"

if condition == True:
    print("The condition")
    print("was True")
elif name == "Roger":
    print("Hello Roger")
elif name == "Syd":
    print("Hello Syd")
elif name == "Flavio":
    print("Hello Flavio")
else:
    print("The condition")
    print("was False")
</code></pre>
<p><code>if</code>和 <code>else</code>也可以内联使用，这让我们可以根据条件返回一个值或另一个值。</p>
<p>例子：</p>
<pre><code class="language-python">a = 2
result = 2 if a == 0 else 3
print(result)  # 3
</code></pre>
<h2 id="lists-in-python">Python列表</h2>
<p>列表是Python中一种基本的数据结构。</p>
<p>使用列表，您可以将多个值组合在一起，并使用一个名称引用它们。</p>
<p>例如：</p>
<pre><code class="language-python">dogs = ["Roger", "Syd"]
</code></pre>
<p>一个列表中可以保存不同数据类型的值：</p>
<pre><code class="language-python">items = ["Roger", 1, "Syd", True]
</code></pre>
<p>您可以使用<code>in</code>运算符检查某个元素是否在列表中：</p>
<pre><code class="language-python">print("Roger" in items)  # True
</code></pre>
<p>当然也可以定义空的列表：</p>
<pre><code class="language-python">items = []
</code></pre>
<p>您可以通过从零开始的索引引用列表中的元素：</p>
<pre><code class="language-python">items[0]  # "Roger"
items[1]  # 1
items[3]  # True
</code></pre>
<p>使用相同的表示法，您可以更改存储在特定索引处的值：</p>
<pre><code class="language-python">items[0] = "Roger"
</code></pre>
<p>您还可以使用<code>index()</code>：</p>
<pre><code class="language-python">items.index(0)  # "Roger"
items.index(1)  # 1
</code></pre>
<p>就像字符串（索引）一样，使用负索引将从末尾开始数：</p>
<pre><code class="language-python">items[-1]  # True
</code></pre>
<p>您还可以使用切片提取列表的一部分：</p>
<pre><code class="language-python">items[0:2]  # ["Roger", 1]
items[2:]  # ["Syd", True]
</code></pre>
<p>使用全局函数<code>len()</code>获取列表中包含的元素数目，这与我们用来获取字符串长度的方法相同：</p>
<pre><code class="language-python">len(items)  # 4
</code></pre>
<p>您可以使用list的<code>append()</code>方法将新元素添加到列表中：</p>
<pre><code class="language-python">items.append("Test")
</code></pre>
<p>或者使用<code>extend()</code>方法：</p>
<pre><code class="language-python">items.extend(["Test"])
</code></pre>
<p>您还可以使用<code>+=</code>运算符：</p>
<pre><code class="language-python">items += ["Test"]

# items is ['Roger', 1, 'Syd', True, 'Test']
</code></pre>
<blockquote>
<p>注意：使用<code>extend()</code>或<code>+=</code>不要忘记方括号。不要执行<code>items += "Test"</code>或<code>items.extend("Test")</code>，否则Python会在列表中添加4个单独的字符，即<code>['Roger', 1, 'Syd', True, 'T'、'e'、's'、't']</code></p>
</blockquote>
<p>使用<code>remove()</code>方法删除元素：</p>
<pre><code class="language-python">items.remove("Test")
</code></pre>
<p>您可以添加多个元素：</p>
<pre><code class="language-python">items += ["Test1", "Test2"]

# or

items.extend(["Test1", "Test2"])
</code></pre>
<p>这些方法会将元素加到列表的末尾。</p>
<p>要在列表中间的特定索引处添加元素，请使用<code>insert()</code>方法：</p>
<pre><code class="language-python">items.insert("Test", 1)  # add "Test" at index 1
</code></pre>
<p>要在特定索引处添加多个项目，您需要使用切片：</p>
<pre><code class="language-python">items[1:1] = ["Test1", "Test2"]
# 译者：这里实际上是先删除再添加，就该例子来说，先删除[1:1]的元素（切片是左闭右开，所有[1:1]没有选中任何元素），再在删除的位置上添加
#。    比如s = [1,2,3];  s[0:2] = ['a', 'b', 'c'];  --&gt; 执行完前面两个语句，s就变为['a', 'b', 'c', 3]
</code></pre>
<p>使用<code>sort()</code>方法对列表进行排序：</p>
<pre><code class="language-python">items.sort()
</code></pre>
<blockquote>
<p>注意：sort()仅在列表包含可比较的值时才有效。例如，无法比较字符串和整数，如果您尝试（对元素之间不可比较的列表进行排序），您将看到到类似<code>TypeError: '&lt;' not supported between 'int' and 'str'</code>的错误。</p>
</blockquote>
<p>（针对字符串排序）<code>sort()</code>方法首先排序大写字母，然后是小写字母。要解决此问题，请使用：</p>
<pre><code class="language-python">items.sort(key=str.lower)
</code></pre>
<p>（使用sort方法）排序会修改原始列表内容。为避免这种情况，您可以先复制列表</p>
<pre><code class="language-python">itemscopy = items[:]
</code></pre>
<p>或者使用全局函数<code>sorted()</code>：</p>
<pre><code class="language-python">print(sorted(items, key=str.lower))
</code></pre>
<p>这将返回一个排好序的新列表，而不是修改原始列表。</p>
<h2 id="tuples-in-python">Python元组</h2>
<p>元组是Python中另一种基本的数据结构。</p>
<p>它允许您创建不可变的对象组。这意味着一旦创建了元组，就无法修改它。您不能添加或删除元组中的元素。</p>
<p>元组的创建方式类似于列表，但是是使用括号而不是方括号：</p>
<pre><code class="language-python">names = ("Roger", "Syd")
</code></pre>
<p>元组是有序的，就像列表一样，所以您可以通过一个索引来获取具体位置的值：</p>
<pre><code class="language-python">names[0]  # "Roger"
names[1]  # "Syd"
</code></pre>
<p>您也可以使用<code>index()</code>方法：</p>
<pre><code class="language-python">names.index('Roger')  # 0
names.index('Syd')  # 1
</code></pre>
<p>与字符串和列表一样，使用负索引将从末尾开始：</p>
<pre><code class="language-python">names[-1]  # True
</code></pre>
<p>您可以使用函数<code>len()</code>计算元组中的元素个数：</p>
<pre><code class="language-python">len(names)  # 2
</code></pre>
<p>您可以使用<code>in</code>运算符检查元素是否在元组中：</p>
<pre><code class="language-python">print("Roger" in names)  # True
</code></pre>
<p>您还可以使用切片提取元组的一部分：</p>
<pre><code class="language-python">names[0:2]  # ('Roger', 'Syd')
names[1:]  # ('Syd',)
</code></pre>
<p>您可以使用全局函数<code>sorted()</code>创建元组排好序的版本：<br>
（译者：请注意，元组没有sort方法，因为元组是不可改变的）</p>
<pre><code class="language-python">sorted(names)
</code></pre>
<p>您可以使用<code>+</code>运算符从现有元组创建一个新元组：</p>
<pre><code class="language-python">newTuple = names + ("Vanille", "Tina")
</code></pre>
<h2 id="dictionaries-in-python">Python字典</h2>
<p>字典是Python中非常重要的一种数据结构。</p>
<p>列表允许您创建值的集合，而字典允许您创建<strong>键/值对</strong>的集合。</p>
<p>这是有一个键/值对的字典示例：</p>
<pre><code class="language-python">dog = { 'name': 'Roger' }
</code></pre>
<p>键可以是任何不可变的值，例如字符串、数字或元组，该值可以是您想要的任何值。</p>
<p>一个字典可以包含多个键/值对：</p>
<pre><code class="language-python">dog = { 'name': 'Roger', 'age': 8 }
</code></pre>
<p>您可以使用此表示法访问单个键对应的值：</p>
<pre><code class="language-python">dog['name']  # 'Roger'
dog['age']  # 8
</code></pre>
<p>使用相同的表示法，您可以更改在特定索引（键）对应的值：</p>
<pre><code class="language-python">dog['name'] = 'Syd'
</code></pre>
<p>另一种方法是使用<code>get()</code>方法，该方法可以添加默认值（译者：即字典中没有该键时返回的值）：</p>
<pre><code class="language-python">dog.get('name')  # 'Roger'
dog.get('test', 'default')  # 'default'
</code></pre>
<p><code>pop()</code>方法检索键的值，然后从字典中删除该键/值对：</p>
<pre><code class="language-python">dog.pop('name')  # 'Roger'
</code></pre>
<p><code>popitem()</code>方法检索并删除最后一个插入字典的键/值对：</p>
<pre><code class="language-python">dog.popitem()
</code></pre>
<p>您可以使用<code>in</code>运算符检查键是否包含在字典中：</p>
<pre><code class="language-python">'name' in dog  # True
</code></pre>
<p>使用<code>keys()</code>方法获取字典中的键，并将结果传递给<code>list()</code>构造函数：</p>
<pre><code class="language-python">list(dog.keys())  # ['name', 'age']
</code></pre>
<p>使用<code>values()</code>方法获取字典中的值，使用<code>items()</code>方法获取键/值对组成的元组：</p>
<pre><code class="language-python">print(list(dog.values()))
# ['Roger', 8]

print(list(dog.items()))
# [('name', 'Roger'), ('age', 8)]
</code></pre>
<p>使用全局函数<code>len()</code>获取字典长度，这与获取字符串或列表的长度相同：</p>
<pre><code class="language-python">len(dog)  # 2
</code></pre>
<p>您可以通过这种方式将新的键/值对添加到字典中：</p>
<pre><code class="language-python">dog['favorite food'] = 'Meat'
</code></pre>
<p>您可以使用<code>del</code>语句从字典中删除键/值对：</p>
<pre><code class="language-python">del dog['favorite food']
</code></pre>
<p>要复制字典，请使用copy()方法：<br>
（译者：这种方式是浅拷贝）</p>
<pre><code class="language-python">dogCopy = dog.copy()
</code></pre>
<h2 id="sets-in-python">Python集合</h2>
<p>集合是Python另一个重要的数据结构。</p>
<p>可以说它像元组一样工作，但集合不是有序的，而且是<strong>可变的</strong>。</p>
<p>或者我们可以说它像字典一样工作，但它们没有键。</p>
<p>集合还有一个不可变的版本，称为<code>frozenset</code>。</p>
<p>您可以使用以下语法创建集合：</p>
<pre><code class="language-python">names = {"Roger", "Syd"}
</code></pre>
<p>您将它们视为数学上的集合，会更好理解。</p>
<p>您可以求两个集合的交集：</p>
<pre><code class="language-python">set1 = {"Roger", "Syd"}
set2 = {"Roger"}

intersect = set1 &amp; set2  # {'Roger'}
</code></pre>
<p>您可以创建两个集合的并集：</p>
<pre><code class="language-python">set1 = {"Roger", "Syd"}
set2 = {"Luna"}

union = set1 | set2
# {'Syd', 'Luna', 'Roger'}
</code></pre>
<p>您可以得到两个集合的差集：</p>
<pre><code class="language-python">set1 = {"Roger", "Syd"}
set2 = {"Roger"}

difference = set1 - set2  # {'Syd'}
</code></pre>
<p>您可以检查一个集合是否是另一个集合的超集（也即一个集合是另一个集合的子集）：</p>
<pre><code class="language-python">set1 = {"Roger", "Syd"}
set2 = {"Roger"}

isSuperset = set1 &gt; set2  # True
</code></pre>
<p>您可以使用全局函数<code>len()</code>计算集合中的元素个数：</p>
<pre><code class="language-python">names = {"Roger", "Syd"}
len(names)  # 2
</code></pre>
<p>您可以通过将集合传递给<code>list()</code>构造函数来获取集合元素的列表：</p>
<pre><code class="language-python">names = {"Roger", "Syd"}
list(names)  # ['Syd', 'Roger']
</code></pre>
<p>您可以使用<code>in</code>运算符检查元素是否在集合中：</p>
<pre><code class="language-python">print("Roger" in names)  # True
</code></pre>
<h2 id="functions-in-python">Python函数</h2>
<p>函数可以创建一组指令，我们在需要时运行这些指令。</p>
<p>函数在Python和其它许多编程语言中是必不可少的。它帮助我们创建有意义的程序，因为我们可以使用函数将程序分解为可管理的部分，并且促进了代码的可读性和重用性。</p>
<p>这是一个名为<code>hello</code>的函数示例，它打印"Hello!"：</p>
<pre><code class="language-python">def hello():
    print('Hello!')
</code></pre>
<p>函数<strong>定义</strong>：有一个名称（<code>hello</code>）和一个由一组指令组成的主体（即冒号后面的部分），主体在右侧缩进一级。</p>
<p>要运行这个函数，我们必须调用它。这是调用函数的语法：</p>
<pre><code class="language-python">hello()
</code></pre>
<p>我们可以调用这个函数一次或多次。</p>
<p>函数名<code>hello</code>非常重要，它应该是描述性的，这样任何调用该函数的人都可以理解它的作用。</p>
<p>一个函数可以接受一个或多个参数：</p>
<pre><code class="language-python">def hello(name):
    print('Hello ' + name + '!')
</code></pre>
<p>这种情况下，我们通过传递参数来调用函数</p>
<pre><code class="language-python">hello('Roger')
</code></pre>
<blockquote>
<p>我们称_parameters_为函数定义中函数所接受的值（形参），称_arguments_为我们调用函数时所传递给函数的值（实参）。对这种区别感到困惑是很正常的。</p>
</blockquote>
<p>如果（调用函数时）未指定参数，则参数可以具有默认值：</p>
<pre><code class="language-python">def hello(name='my friend'):
    print('Hello ' + name + '!')

hello()
# Hello my friend!
</code></pre>
<p>以下是如何接受多个参数：</p>
<pre><code class="language-python">def hello(name, age):
    print('Hello ' + name + ', you are ' + str(age) + ' years old!')
</code></pre>
<p>在这种情况下，我们调用函数并传递一组参数：</p>
<pre><code class="language-python">hello('Roger', 8)
</code></pre>
<p>形参通过引用传递。Python中的所有内容都是对象，但其中一些是不可变的，包括整数、布尔值、浮点数、字符串和元组。这意味着如果您将它们作为参数传递给函数，并在函数内部修改它们的值，则新值不会反映在函数外部：</p>
<pre><code class="language-python">def change(value):
    value = 2

val = 1
change(val)

print(val)  # 1
</code></pre>
<p>如果您传递一个可变的对象，并且（在函数内部）更改了它的一个属性，则该更改将反映在外部。</p>
<p>函数可以使用<code>return</code>语句返回一个值。例如我们返回 <code>name</code> 参数：</p>
<pre><code class="language-python">def hello(name):
    print('Hello ' + name + '!')
    return name
</code></pre>
<p>当函数执行到<code>return</code>语句时，该函数结束。</p>
<p>我们可以省略该返回值：</p>
<pre><code class="language-python">def hello(name):
    print('Hello ' + name + '!')
    return
</code></pre>
<p>我们可以在条件中包含return语句，这是在不满足起始条件时结束函数的常用方法：</p>
<pre><code class="language-python">def hello(name):
    if not name:
        return
    print('Hello ' + name + '!')
</code></pre>
<p>如果我们调用该函数并传递一个计算结果为<code>False</code>的表达式，比如一个空字符串，函数在到达<code>print()</code>语句之前终止。</p>
<p>您可以使用逗号分隔来返回多个值：</p>
<pre><code class="language-python">def hello(name):
    print('Hello ' + name + '!')
    return name, 'Roger', 8
</code></pre>
<p>在这种情况下，调用 <code>hello('Syd')</code> 返回值是一个包含这 3 个值的元组：<code>('Syd', 'Roger', 8)</code>。</p>
<h2 id="objects-in-python">Python对象</h2>
<p>Python中的一切都是对象。</p>
<p>原始类型（整数、字符串、浮点数……）的值也是对象。 同时列表、元组、字典和一切也都是对象。</p>
<p>对象具有可以使用点语法访问的<strong>属性</strong>和<strong>方法</strong>。</p>
<p>例如，尝试定义一个<code>int</code>类型的新变量：</p>
<pre><code class="language-python">age = 8
</code></pre>
<p><code>age</code>现在可以访问为<code>int</code>对象定义的属性和方法。</p>
<p>这包括访问该数字的实部和虚部，例如：</p>
<pre><code class="language-python">print(age.real)  # 8
print(age.imag)  # 0

print(age.bit_length())  # 4

# bit_length()方法返回该数字的二进制表示法所需的位数
</code></pre>
<p>列表类型的变量可以使用一组方法：</p>
<pre><code class="language-python">items = [1, 2]
items.append(3)
items.pop()
</code></pre>
<p>这些（可使用的）方法取决于变量的数据类型。</p>
<p>Python提供的全局函数<code>id()</code>可让您检查特定对象在内存中的位置。</p>
<pre><code class="language-python">id(age)  # 140170065725376
</code></pre>
<blockquote>
<p>您（电脑上查看的age）的内存地址值会不一样——这里只是作为一个例子来展示。</p>
</blockquote>
<p>如果给变量赋不同的值，它的地址会改变，因为变量已经指向存储在内存中另一个位置的另一个值：</p>
<pre><code class="language-python">age = 8

print(id(age))  # 140535918671808

age = 9

print(id(age))  # 140535918671840
</code></pre>
<p>但是，如果您使用对象的方法修改该对象，其内存地址将保持不变：</p>
<pre><code class="language-python">items = [1, 2]

print(id(items))  # 140093713593920

items.append(3)

print(items)  # [1, 2, 3]
print(id(items))  # 140093713593920
</code></pre>
<p>仅当您将变量重新赋一个值时，地址才会更改。</p>
<p>一些类型的对象是_可变的_，而另一些是_不可变的_。这取决于对象本身。</p>
<p>如果对象提供改变其内容的方法，那么它是可变的。否则它是不可变的。</p>
<p>Python定义的大多数类型都是不可变的， 例如<code>int</code> ，没有任何方法可以改变它的值。如果您增加它的值，</p>
<pre><code class="language-python">age = 8
age = age + 1

# 或者

age += 1
</code></pre>
<p>然后您使用<code>id(age)</code>检查，您会发现<code>age</code>前后指向不同的内存位置。原来的值并没有发生改变，age只是指向另一个值。</p>
<h2 id="loops-in-python">Python循环</h2>
<p>循环是编程的重要组成部分。</p>
<p>在 Python 中，我们有2种循环：<strong>while循环</strong>和<strong>for循环</strong>。</p>
<h3 id="pythonwhile">Python中的<code>while</code>循环</h3>
<p><code>while</code>循环是使用<code>while</code>关键字定义的，它重复执行自己的块，直到判断条件为<code>False</code>：</p>
<pre><code class="language-python">condition = True
while condition == True:
    print("The condition is True")
</code></pre>
<p>这是一个永远不会停下来的<strong>无限循环</strong>。</p>
<p>让我们在第一次迭代后立即停止循环：</p>
<pre><code class="language-python">condition = True
while condition == True:
    print("The condition is True")
    condition = False

print("After the loop")
</code></pre>
<p>在这种情况下，将执行第一次迭代，因为此时判断条件为<code>True</code>。在第二次迭代时，判断条件为<code>False</code>，因此执行循环外的下一条指令。</p>
<p>通常有一个计数器用于在一些周期后停止迭代：</p>
<pre><code class="language-python">count = 0
while count &lt; 10:
    print("The condition is True")
    count = count + 1

print("After the loop")
</code></pre>
<h3 id="pythonfor">Python中的<code>for</code>循环</h3>
<p>使用<code>for</code>循环，我们可以让Python执行一个预先确定循环次数的代码块，并且不需要单独的变量和条件来检查它的值。</p>
<p>例如，我们可以迭代列表中的元素：</p>
<pre><code class="language-python">items = [1, 2, 3, 4]
for item in items:
    print(item)
</code></pre>
<p>或者，您可以使用<code>range()</code>函数迭代特定次数：</p>
<pre><code class="language-python">for item in range(04):
    print(item)
</code></pre>
<p><code>range(4)</code>创建一个从0开始并包含4个元素的序列：<code>[0, 1, 2, 3]</code>。</p>
<p>如果要获取索引，您应该将序列包装到<code>enumerate()</code>函数中：</p>
<pre><code class="language-python">items = [1, 2, 3, 4]
for index, item in enumerate(items):
    print(index, item)
</code></pre>
<h3 id="pythonbreakcontinue">Python中的<code>Break</code>和<code>continue</code></h3>
<p><code>while</code>和 <code>for</code>循环都可以在代码块内被中断，这需要使用两个特殊关键字：<code>break</code>和<code>continue</code>。</p>
<p><code>continue</code>停止当前迭代并告诉Python执行下一个迭代。</p>
<p><code>break</code>完全停止循环，并继续执行循环外的下一条指令。</p>
<p>这里第一个示例打印 <code>1, 3, 4</code>。第二个示例打印 <code>1</code>：</p>
<pre><code class="language-python">items = [1, 2, 3, 4]
for item in items:
    if item == 2:
        continue
    print(item)
</code></pre>
<pre><code class="language-python">items = [1, 2, 3, 4]
for item in items:
    if item == 2:
        break
    print(item)
</code></pre>
<h2 id="classes-in-python">Python类</h2>
<p>除了使用Python提供的数据类型之外，我们还可以声明自定义的类，并使用类实例化对象。</p>
<p>对象是类的实例。类是对象的类型。</p>
<p>我们可以这样定义一个类：</p>
<pre><code class="language-python">class &lt;class_name&gt;:
    # 自定义的类
</code></pre>
<p>例如，让我们定义一个Dog类</p>
<pre><code class="language-python">class Dog:
    # Dog类
</code></pre>
<p>一个类里面可以定义方法：</p>
<pre><code class="language-python">class Dog:
    # Dog类
    def bark(self):
        print('WOF!')
</code></pre>
<blockquote>
<p><code>self</code>作为方法的参数，指向当前实例对象，定义类的方法时必须指定<code>self</code>。（译者：大多数情况下如此，有些特殊的方法不用指定）</p>
</blockquote>
<p>我们使用以下语法创建一个类的实例对象，即创建一个<strong>object</strong>：</p>
<pre><code class="language-python">roger = Dog()
</code></pre>
<p>现在<code>roger</code>是Dog类型的对象。</p>
<p>如果运行</p>
<pre><code class="language-python">print(type(roger))
</code></pre>
<p>您会看到<code>&lt;class '__main__.Dog'&gt;</code></p>
<p>当我们从类中创建新对象时，我们使用一种被称为构造函数的特殊方法<code>__init__()</code>来初始化一个或多个属性：</p>
<pre><code class="language-python">class Dog:
    # the Dog class
    def __init__(self, name, age):
        self.name = name
        self.age = age

    def bark(self):
        print('WOF!')
</code></pre>
<p>我们这样使用它：</p>
<pre><code class="language-python">roger = Dog('Roger', 8)
print(roger.name)  # 'Roger'
print(roger.age)  # 8

roger.bark()  # 'WOF!'
</code></pre>
<p>类的一个重要特性是继承。</p>
<p>我们创建一个可以使用<code>walk()</code>方法的Animal 类：</p>
<pre><code class="language-python">class Animal:
    def walk(self):
        print('Walking..')
</code></pre>
<p>然后Dog类继承Animal类：</p>
<pre><code class="language-python">class Dog(Animal):
    def bark(self):
        print('WOF!')
</code></pre>
<p>现在创建<code>Dog</code>类的新对象，它将具有<code>walk()</code>方法，因为<code>Dog</code>类继承自<code>Animal</code>类：</p>
<pre><code class="language-python">roger = Dog()
roger.walk()  # 'Walking..'
roger.bark()  # 'WOF!'
</code></pre>
<h2 id="modules-in-python">Python模块</h2>
<p>每个Python文件都是一个模块。</p>
<p>您可以从其它文件导入模块，这是任何具有一定复杂性的程序的基础，因为它促进了合理的组织结构和代码重用。</p>
<p>在典型的Python程序中，一个文件作为入口点，那么其它文件是模块，并公开可以从模块中调用的函数。（译者：不只是可以公开函数，类、常量等等都行）</p>
<p>文件<code>dog.py</code>包含以下代码：</p>
<pre><code class="language-python">def bark():
    print('WOF!')
</code></pre>
<p>我们可以使用<code>import</code>从另一个文件中导入这个模块。一旦我们这样做了，我们就可以使用<code>dog.bark()</code>来引用该函数：</p>
<pre><code class="language-python">import dog

dog.bark()
</code></pre>
<p>或者，我们可以使用<code>from .. import</code>语法直接导入函数：</p>
<pre><code class="language-python">from dog import bark

bark()
</code></pre>
<p>第一个策略导入文件中定义的所有内容。</p>
<p>第二个策略只选择导入我们需要的东西。</p>
<p>这些模块（的形式）取决于您的程序，导入（方法）取决于所导入模块（即文件）在文件系统中的位置。</p>
<p>假设您将<code>dog.py</code>文件放在<code>lib</code>文件夹中。</p>
<p>在该文件夹中，您需要创建一个名为<code>__init__.py</code>的空文件来告诉Python该文件夹包含模块。</p>
<p>现在您可以选择从<code>lib</code>中导入<code>dog</code>：</p>
<pre><code class="language-py">from lib import dog

dog.bark()
</code></pre>
<p>或者您可以从<code>lib.dog</code>导入特定<code>dog</code>模块函数：</p>
<pre><code class="language-py">from lib.dog import bark

bark()
</code></pre>
<h2 id="the-python-standard-library">Python标准库</h2>
<p>Python通过其<strong>标准库</strong>公开了许多内置功能。</p>
<p>标准库是各种应用程序的集合，包括数学应用，代码调试，以及图形用户界面创建等等。</p>
<p>您可以在此处找到标准库模块的完整列表：<a href="https://docs.python.org/3/library/index.html">https://docs.python.org/3/library/index.html</a></p>
<p>一些比较重要的模块是：</p>
<ul>
<li><code>math</code> 数学计算相关应用程序</li>
<li><code>re</code> 正则表达式的使用</li>
<li><code>json</code> 处理json数据</li>
<li><code>datetime</code> 处理日期</li>
<li><code>sqlite3</code> 使用SQLite</li>
<li><code>os</code> 操作系统实用程序</li>
<li><code>random</code> 生成随机数</li>
<li><code>statistics</code> 数学统计相关应用程序</li>
<li><code>requests</code> 执行HTTP网络请求</li>
<li><code>http</code> 创建HTTP服务器</li>
<li><code>urllib</code> 管理URL</li>
</ul>
<p>接下来介绍如何_使用_标准库的一个模块。您已经知道如何使用自己创建的模块，即从程序文件夹中的其它文件导入。</p>
<p>标准库提供的模块也是如此使用：</p>
<pre><code class="language-python">import math

math.sqrt(4)  # 2.0
</code></pre>
<p>或者</p>
<pre><code class="language-python">from math import sqrt

sqrt(4)  # 2.0
</code></pre>
<p>我们很快将单独探索最重要的模块，以了解我们可以用其做什么。</p>
<h2 id="the-pep8-python-style-guide">Python PEP8风格指导</h2>
<p>编写代码时，应遵守所使用的编程语言的一些约定。</p>
<p>如果您从一开始就学习正确的命名和格式约定，那么将更容易阅读其他人编写的代码，同样其他人也会发现您的代码易于阅读。</p>
<p>Python在PEP8样式指南中定义了其代码风格约定。PEP即_Python Enhancement Proposals_，它描述了Python语言所有增强和讨论的地方。</p>
<p>有很多PEP提案，都可以在<a href="https://www.python.org/dev/peps/">https://www.python.org/dev/peps/</a> 上找到。</p>
<p>PEP8是最早和最重要的提案之一，它定义了格式和以"pythonic"方式编写Python代码的一些规则。</p>
<p>您可以在此处阅读其完整内容：<a href="https://www.python.org/dev/peps/pep-0008/">https://www.python.org/dev/peps/pep-0008/</a> ，下面是几点总结，您可以从这里快速开始：</p>
<ul>
<li>使用空格而不是制表符缩进</li>
<li>使用4个空格缩进</li>
<li>Python文件用UTF-8编码</li>
<li>一行代码最多80列</li>
<li>每个语句写在自己所在的一行上</li>
<li>函数、变量名和文件名使用小写，单词之间用下划线分隔（例如snake_case）</li>
<li>类名单词首字母大写（例如CamelCase）</li>
<li>包名是小写的，单词之间没有下划线</li>
<li>不应该改变的常量全用大写字母</li>
<li>变量名应该有意义</li>
<li>添加有用的注释，但应该避免为非常易懂的代码添加注释</li>
<li>在运算符两边添加空格</li>
<li>不要使用不必要的空格</li>
<li>在函数（的定义）前添加一个空行</li>
<li>在类中的方法之间添加一个空行</li>
<li>在函数/方法内部，可以使用空行分隔相关的代码块，以提高可读性</li>
</ul>
<h2 id="debugging-in-python">Python代码调试</h2>
<p>调试代码是您应该学习的最佳技能之一，因为在许多困难的情况下，它将为您提供帮助。</p>
<p>每种编程语言都有其调试器。Python使用<code>pdb</code>调试代码，可通过标准库获得。</p>
<p>您可以通过在代码中添加一个断点来进行调试：</p>
<pre><code class="language-python">breakpoint()
</code></pre>
<blockquote>
<p>如果需要，您可以添加更多断点。</p>
</blockquote>
<p>当Python解释器在您的代码中遇到断点时，它会停止执行代码，并会告诉您下一条将运行的指令是什么。</p>
<p>接下来您可以做一些事情。</p>
<p>您可以键入任何变量的名称来检查其值。</p>
<p>您可以按<code>n</code>跳到当前函数的下一行。如果下一行代码调用了函数，调试器不会进入它们，并将它们视为"黑匣子"。</p>
<p>您可以按 <code>s</code>跳到当前函数的下一行。如果下一行是调用一个函数，则调试器会进入该函数，然后您可以一次运行该函数的一条指令。</p>
<p>您可以按<code>c</code>继续正常执行剩下的程序，而无需逐步执行。</p>
<p>您可以按<code>q</code>停止程序的执行。</p>
<p>调试对于评估程序的结果很有用，当您有复杂的迭代或要修改的算法时，了解如何使用它尤其有用。</p>
<h2 id="variable-scope-in-python">Python变量作用域</h2>
<p>当您声明一个变量时，该变量在程序的某些部分中可见，这具体取决于您声明它的位置。</p>
<p>如果您在函数之外声明它，则该变量对声明之后的任何代码都是可见的，包括（这之后定义的）函数：</p>
<pre><code class="language-python">age = 8

def test():
    print(age)

print(age)  # 8
test()  # 8
</code></pre>
<p>我们称这种变量为<strong>全局变量</strong>。</p>
<p>如果您在函数内部定义变量，则该变量是<strong>局部变量</strong>，并且仅在该函数内部可见。在函数之外，它是不可访问的：</p>
<pre><code class="language-python">def test():
    age = 8
    print(age)

test()  # 8

print(age)
# 这些这个print会报错 NameError: name 'age' is not defined
</code></pre>
<h2 id="how-to-accept-arguments-from-the-command-line-in-python">Python接收从命令行传入的参数</h2>
<p>当我们从命令行调用程序时，Python提供了几种方法来处理传递的参数。</p>
<p>到目前为止，您已经使用过REPL来执行程序，或使用如下方法执行Python代码</p>
<pre><code class="language-sh">python &lt;文件名&gt;.py
</code></pre>
<p>（像上面）这样做时，您可以传递附加的参数和选项，如下所示：</p>
<pre><code class="language-sh">python &lt;文件名&gt;.py &lt;参数1&gt;
python &lt;文件名&gt;.py &lt;参数1&gt; &lt;参数2&gt;
</code></pre>
<p>处理这些参数的基本方法是使用标准库中的<code>sys</code>模块。</p>
<p>您可以获取在<code>sys.argv</code>列表中传递的参数：</p>
<pre><code class="language-python">import sys
print(len(sys.argv))
print(sys.argv)
</code></pre>
<p><code>sys.argv</code>列表的第一项包含所运行文件的名称，例如 <code>['main.py']</code>。</p>
<p>这是一种简单的方法，但您必须自己做很多工作。您需要验证参数，确保它们的类型是正确的，如果用户没有正确使用程序，您需要向他们打印反馈信息。</p>
<p>Python在标准库中提供了另一个包来帮助您：<code>argparse</code>。</p>
<p>您首先导入<code>argparse</code>并调用<code>argparse.ArgumentParser()</code>，传递程序的描述：</p>
<pre><code class="language-python">import argparse

parser = argparse.ArgumentParser(
    description='This program prints the name of my dogs'
)
</code></pre>
<p>然后继续添加想要接受的参数。<br>
例如，在下面这个程序中，我们接受一个<code>-c</code>选项来传递颜色，就像这样（执行代码文件）：<code>python program.py -c red</code></p>
<pre><code class="language-python">import argparse

parser = argparse.ArgumentParser(
    description='This program prints a color HEX value'
)

parser.add_argument('-c', '--color', metavar='color', required=True, help='the color to search for')

args = parser.parse_args()

print(args.color)  # 'red'
</code></pre>
<p>如果未指定参数，程序将报错：</p>
<pre><code>➜  python python program.py
usage: program.py [-h] -c color
program.py: error: the following arguments are required: -c

program.py: error: 程序运行需要如下参数: -c
</code></pre>
<p>您可以使用<code>choices</code>将选项设置为一组特定值：</p>
<pre><code class="language-python">parser.add_argument('-c', '--color', metavar='color', required=True, choices={'red','yellow'}, help='the color to search for')
</code></pre>
<pre><code>➜  python python program.py -c blue
usage: program.py [-h] -c color
program.py: error: argument -c/--color: invalid choice: 'blue' (choose from 'yellow', 'red')

program.py: error: argument -c/--color: 无效的选择: 'blue' (该选项只能为'yellow'或'red')
</code></pre>
<p>还有更多选择，但以上是基础。</p>
<p>也有提供此功能的社区包，例如<a href="https://click.palletsprojects.com/en/7.x/">Click</a>和<a href="https://python-prompt-toolkit.readthedocs.io/en/master/index.html">Python Prompt Toolkit</a>。</p>
<h2 id="lambda-functions-in-python">Python的Lambda函数</h2>
<p>Lambda函数（也称为匿名函数）是没有名称且只有一个表达式作为其主体的小型函数。</p>
<p>在Python中，它们是使用<code>lambda</code>关键字定义的：</p>
<pre><code class="language-python">lambda &lt;参数&gt; : &lt;表达式&gt;
</code></pre>
<p>主体必须是单个表达式，而不是语句。</p>
<blockquote>
<p>这很重要：表达式返回值，语句不返回。</p>
</blockquote>
<p>最简单的lambda函数示例是将数字的值加倍：</p>
<pre><code class="language-python">lambda num : num * 2
</code></pre>
<p>Lambda函数可以接受更多参数：</p>
<pre><code class="language-python">lambda a, b : a * b
</code></pre>
<p>无法直接调用Lambda函数，但您可以将它们分配给变量：</p>
<pre><code class="language-python">multiply = lambda a, b : a * b

print(multiply(2, 2))  # 4
</code></pre>
<p>Lambda函数的实用性在于与其它Python功能结合使用，例如结合<code>map()</code>、<code>filter()</code>和<code>reduce()</code>。</p>
<h2 id="recursion-in-python">Python递归</h2>
<p>Python中的函数可以调用自身，这就是递归。递归在许多情况下都非常有用。</p>
<p>解释递归的常用方法是实现阶乘计算。</p>
<p>一个数字<code>n</code>的阶乘是数字<code>n</code>乘以<code>n-1</code>，再乘以<code>n-2</code>，以此类推，直到数字<code>1</code>：</p>
<pre><code>3! = 3 * 2 * 1 = 6
4! = 4 * 3 * 2 * 1 = 24
5! = 5 * 4 * 3 * 2 * 1 = 120
</code></pre>
<p>使用递归，我们可以编写一个计算任意数阶乘的函数：</p>
<pre><code class="language-python">def factorial(n):
    if n == 1: return 1
    return n * factorial(n-1)

print(factorial(3))  # 6
print(factorial(4))  # 24
print(factorial(5))  # 120
</code></pre>
<p>如果在 <code>factorial()</code> 函数中调用<code>factorial(n)</code>而不是<code>factorial(n-1)</code>，则会导致无限递归。 默认情况下，Python将在1000次调用时停止递归，此时您将收到<code>RecursionError</code>错误。</p>
<p>递归在很多地方都有用，它可以帮助我们在没有其它更好方法的情况下简化代码，所以了解这种技术是件好事。</p>
<h2 id="nested-functions-in-python">Python嵌套函数</h2>
<p>Python中函数可以嵌套在其它函数中。</p>
<p>在函数内部定义的函数仅在该函数内可见。</p>
<p>这对于创建在函数内有用，但在函数外无用的程序很有用。</p>
<p>您可能会问：如果它没有害处，我为什么要“隐藏”这个功能？</p>
<p>因为最好隐藏函数本地并且在其它地方没有用的功能。</p>
<p>另外，这样我们可以使用闭包（稍后会详细介绍）。</p>
<p>这里是一个例子：</p>
<pre><code class="language-python">def talk(phrase):
    def say(word):
        print(word)

    words = phrase.split(' ')
    for word in words:
        say(word)

talk('I am going to buy the milk')
</code></pre>
<p>如果要从内部函数访问外部函数中定义的变量，首先需要将其声明为<code>nonlocal</code>：</p>
<pre><code class="language-python">def count():
    count = 0

    def increment():
        nonlocal count
        count = count + 1
        print(count)

    increment()

count()
</code></pre>
<p>这对闭包特别有用，我们将在接下来的说明中看到。</p>
<h2 id="closures-in-python">Python闭包</h2>
<p>如果函数返回一个嵌套函数，则该嵌套函数可以访问在该函数中定义的变量，即使该函数不再处于运行状态。</p>
<p>这是一个简单的计数器示例。</p>
<pre><code class="language-python">def counter():
    count = 0

    def increment():
        nonlocal count
        count = count + 1
        return count

    return increment

increment = counter()

print(increment())  # 1
print(increment())  # 2
print(increment())  # 3
</code></pre>
<p>我们返回<code>increment()</code>这个内部函数，即使<code>counter()</code>函数已经结束，<code>increment</code>仍然可以访问<code>count</code>变量的状态。</p>
<h2 id="decorators-in-python">Python装饰器</h2>
<p>装饰器是一种可以以任何方式增强或改变函数工作方式的方法。</p>
<p>装饰器是用<code>@</code>符号定义的，<code>@</code>后面跟装饰器名称，（装饰器用在）在函数定义之前。</p>
<p>例子：</p>
<pre><code class="language-python">@logtime
def hello():
    print('hello!')
</code></pre>
<p>这个<code>hello</code>函数分配了<code>logtime</code>装饰器。</p>
<p>每当我们调用<code>hello()</code>时，装饰器也都会被调用。</p>
<p>装饰器是一个以函数为参数的函数，它将（被装饰的）函数包装在内部函数中，该内部函数执行必须完成的工作，然后返回这个内部函数。 换句话说：</p>
<pre><code class="language-python">def logtime(func):
    def wrapper():
        # do something before
        val = func()
        # do something after
        return val
    return wrapper
</code></pre>
<h2 id="docstrings-in-python">Python文档字符串</h2>
<p>文档非常重要，不仅可以用于告知其他人（自己写的）函数/类/方法/模块的目标是什么，还可以帮助您（在较长时间后）理解自己的代码。</p>
<p>当您在6或12个月后会看您的的代码时，可能不记得写代码时脑海中的所有想法。这个时候阅读您的代码并理解它在做什么将变得非常困难。</p>
<p>注释是帮助自己（和他人）摆脱这种困境的一种方式：</p>
<pre><code class="language-python"># this is a comment

num = 1  # this is another comment
</code></pre>
<p>另一种方法是使用<strong>docstrings</strong>。</p>
<p>文档字符串的实用性在于它们遵循约定，因此它们可以被自动处理。</p>
<p>这是您为函数定义文档字符串的方式：</p>
<pre><code class="language-python">def increment(n):
    """Increment a number"""
    return n + 1
</code></pre>
<p>这是为类和方法定义文档字符串的方式：</p>
<pre><code class="language-python">class Dog:
    """A class representing a dog"""
    def __init__(self, name, age):
        """Initialize a new dog"""
        self.name = name
        self.age = age

    def bark(self):
        """Let the dog bark"""
        print('WOF!')
</code></pre>
<p>通过在文件顶部放置一个文档字符串来解释记录一个模块，例如，假设这是<code>dog.py</code>：</p>
<pre><code class="language-python">"""Dog module

This module does ... bla bla bla and provides the following classes:

- Dog
...
"""

class Dog:
    """A class representing a dog"""
    def __init__(self, name, age):
        """Initialize a new dog"""
        self.name = name
        self.age = age

    def bark(self):
        """Let the dog bark"""
        print('WOF!')
</code></pre>
<p>文档字符串可以跨越多行：</p>
<pre><code class="language-python">def increment(n):
    """Increment
    a number
    """
    return n + 1
</code></pre>
<p>Python将处理这些（文档字符串），您可以使用全局函数<code>help()</code>来获取类/方法/函数/模块的文档。</p>
<p>例如调用<code>help(increment)</code>会给返回这个：</p>
<pre><code>Help on function increment in module
__main__:

increment(n)
    Increment
    a number
</code></pre>
<p>格式化文档字符串有许多不同的标准，您可以选择遵守自己喜欢的标准。</p>
<p>我喜欢谷歌的标准： <a href="https://github.com/google/styleguide/blob/gh-pages/pyguide.md#38-comments-and-docstrings">https://github.com/google/styleguide/blob/gh-pages/pyguide.md#38-comments-and-docstrings</a></p>
<p>（遵循）标准可以使用工具来提取文档字符串并自动为您的代码生成文档。</p>
<h2 id="introspection-in-python">Python反射</h2>
<p>可以使用<strong>反射</strong>来分析函数、变量和对象。</p>
<p>首先，使用全局函数<code>help()</code>（如果以文档字符串的形式提供）我们可以获得文档。</p>
<p>然后，您可以使用print()获取有关函数的信息：</p>
<pre><code class="language-python">def increment(n):
    return n + 1

print(increment)

# &lt;function increment at 0x7f420e2973a0&gt;
</code></pre>
<p>或者（获取）对象（的信息）：</p>
<pre><code class="language-python">class Dog():
    def bark(self):
        print('WOF!')

roger = Dog()

print(roger)

# &lt;__main__.Dog object at 0x7f42099d3340&gt;
</code></pre>
<p>我们可以使用<code>type()</code>函数获取对象的类型：</p>
<pre><code class="language-python">print(type(increment))
# &lt;class 'function'&gt;

print(type(roger))
# &lt;class '__main__.Dog'&gt;

print(type(1))
# &lt;class 'int'&gt;

print(type('test'))
# &lt;class 'str'&gt;
</code></pre>
<p>全局函数<code>dir()</code>可以找出对象的所有方法和属性：</p>
<pre><code class="language-python">print(dir(roger))

# ['__class__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__le__', '__lt__', '__module__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__', 'bark']
</code></pre>
<p>全局函数<code>id()</code>显示任意对象在内存中的位置：</p>
<pre><code class="language-python">print(id(roger))  # 140227518093024
print(id(1))  # 140227521172384
</code></pre>
<p>这对于检查两个变量是否指向同一个对象会很有用。</p>
<p><code>inspect</code>标准库模块为我们提供了更多获取对象信息的工具，您可以在<a href="https://docs.python.org/3/library/inspect.html">这里</a>查看</p>
<h2 id="annotations-in-python">Python注解</h2>
<p>Python是动态类型的，我们不必指定变量、函数参数或函数返回值的类型。</p>
<p>注解允许我们（可选地）这样做。</p>
<p>这是一个没有注解的函数：</p>
<pre><code class="language-python">def increment(n):
    return n + 1
</code></pre>
<p>这是带有注解的相同函数：</p>
<pre><code class="language-python">def increment(n: int) -&gt; int:
    return n + 1
</code></pre>
<p>您还可以注解变量：</p>
<pre><code class="language-python">count: int = 0
</code></pre>
<p>Python将忽略这些注解。 一个名为<a href="http://mypy-lang.org/"><code>mypy</code></a>的工具可以独立运行，也可以集成到VS Code或PyCharm等IDE中，以便在您编码时自动检查静态类型错误。它还将帮助您在运行代码之前捕获类型不匹配的错误。</p>
<p>这是一个很大的帮助，尤其是当您的软件规模变得很大并且需要重构代码时。</p>
<h2 id="exceptions-in-python">Python异常</h2>
<p>处理错误很重要，Python为我们提供了异常处理来做到这一点。</p>
<p>如果将代码行包装到<code>try:</code>块中：</p>
<pre><code class="language-python">try:
    # 一些代码
</code></pre>
<p>如果发生错误，Python会提醒您，您可以使用<code>except</code>块确认发生了哪种错误：</p>
<pre><code class="language-python">try:
    # 一些代码
except &lt;ERROR1&gt;:
    # 处理 &lt;ERROR1&gt;
except &lt;ERROR2&gt;:
    # 处理 &lt;ERROR2&gt;
</code></pre>
<p>要捕获所有异常，您可以使用不包含任何错误类型的<code>except</code>块：</p>
<pre><code class="language-python">try:
    # 一些代码
except &lt;ERROR1&gt;:
    # 处理 &lt;ERROR1&gt;
except:
    # 捕获其它所有错误
</code></pre>
<p>如果没有发现异常，则将运行<code>else</code>块：</p>
<pre><code class="language-python">try:
    # 一些代码
except &lt;ERROR1&gt;:
    # 处理 &lt;ERROR1&gt;
except &lt;ERROR2&gt;:
    # 处理 &lt;ERROR2&gt;
else:
    # 没有抛出异常，代码成功运行
</code></pre>
<p><code>finally</code>块允许您在任何情况下执行某些操作，无论是否发生错误：</p>
<pre><code class="language-python">try:
    # 一些代码
except &lt;ERROR1&gt;:
    # 处理 &lt;ERROR1&gt;
except &lt;ERROR2&gt;:
    # 处理 &lt;ERROR2&gt;
else:
    # 没有抛出异常，代码成功运行
finally:
    # 任何情况下都将运行的代码
</code></pre>
<p>将发生的具体错误取决于您正在执行的操作。</p>
<p>例如，如果您正在读取一个文件，可能会得到一个<code>EOFError</code>。如果您将一个数除以零，将会得到一个<code>ZeroDivisionError</code>。如果发生类型转换问题，您可能会得到一个<code>TypeError</code>。</p>
<p>试试这个代码：</p>
<pre><code class="language-python">result = 2 / 0
print(result)
</code></pre>
<p>程序将因错误而终止：</p>
<pre><code>Traceback (most recent call last):
  File "main.py", line 1, in &lt;module&gt;
    result = 2 / 0
ZeroDivisionError: division by zero
</code></pre>
<p>并且错误（代码行）之后的代码将不会被执行。</p>
<p>在<code>try:</code>块中添加该操作可以让我们优雅地恢复（错误）并继续执行程序：</p>
<pre><code class="language-python">try:
    result = 2 / 0
except ZeroDivisionError:
    print('Cannot divide by zero!')
finally:
    result = 1

print(result)  # 1
</code></pre>
<p>您也可以在自己的代码中使用<code>raise</code>语句引发异常：</p>
<pre><code class="language-python">raise Exception('An error occurred!')
</code></pre>
<p>这会抛出一个异常，您可以使用以下方法拦截它：</p>
<pre><code class="language-python">try:
    raise Exception('An error occurred!')
except Exception as error:
    print(error)
</code></pre>
<p>您还可以扩展Exception来定义自己的异常类：</p>
<pre><code class="language-python">class DogNotFoundException(Exception):
    pass
</code></pre>
<blockquote>
<p>这里<code>pass</code>的意思是“什么都没有”，当我们定义一个没有方法的类或没有代码的函数时，我们必须使用它。</p>
</blockquote>
<pre><code class="language-python">try:
    raise DogNotFoundException()
except DogNotFoundException:
    print('Dog not found!')
</code></pre>
<h2 id="the-with-statement-in-python">Python中with语句</h2>
<p><code>with</code>语句对于简化异常处理非常有帮助。</p>
<p>例如，在处理文件时，每次打开文件都必须记得关闭它。</p>
<p><code>with</code>使这个过程变得透明（即对程序员不可见）。</p>
<p>（使用<code>with</code>）可以不像下面这样写：</p>
<pre><code class="language-python">filename = '/Users/flavio/test.txt'

try:
    file = open(filename, 'r')
    content = file.read()
    print(content)
finally:
    file.close()
</code></pre>
<p>您可以这样写：</p>
<pre><code class="language-python">filename = '/Users/flavio/test.txt'

with open(filename, 'r') as file:
    content = file.read()
    print(content)
</code></pre>
<p>换句话说，Python有内置的隐式异常处理，其会自动为我们调用<code>close()</code>。</p>
<p>上面的例子只是为了介绍<code>with</code>的功能，而不是说它仅在处理文件方面对我们有帮助。</p>
<h2 id="how-to-install-3rd-party-packages-in-python-using-pip">Python如何使用pip安装第三方包</h2>
<p>Python标准库包含大量实用的程序，可以简化我们的开发需求，但是没有什么能满足_一切_。</p>
<p>这就是个人和公司创建第三方包，并将它们作为开源软件提供给整个社区的原因。</p>
<p>这些模块都收集在一个地方，可在<a href="https://pypi.org">https://pypi.org</a> 获得<strong>Python包索引</strong>，并且可以使用<code>pip</code>将它们（第三方模块）安装在您的系统上。</p>
<p>在撰写本文时，有超过270,000个免费第三方包可供我们使用。</p>
<blockquote>
<p>如果您按照Python安装说明进行操作，您应该已经安装了 <code>pip</code>。</p>
</blockquote>
<p>使用命令<code>pip install</code>可以安装任何第三方包：</p>
<pre><code>pip install &lt;package&gt;
</code></pre>
<p>或者，如果您确实遇到了问题，也可以通过<code>python -m</code>运行它：</p>
<pre><code>python -m pip install &lt;package&gt;
</code></pre>
<p>例如，您可以安装 <a href="https://pypi.org/project/requests/"><code>requests</code></a> 包，这是一个流行的 HTTP 库：</p>
<pre><code>pip install requests
</code></pre>
<p>一旦这样做，它就可以用于您所有的Python脚本，因为包是全局安装的。</p>
<p>（第三方包安装的）具体位置取决于您的操作系统。</p>
<p>在运行Python 3.9的macOS上，位置是<code>/Library/Frameworks/Python.framework/Versions/3.9/lib/python3.9/site-packages</code>。</p>
<p>使用以下命令将第三方包升级到最新版本：</p>
<pre><code>pip install –U &lt;package&gt;
</code></pre>
<p>使用以下命令安装指定版本的第三方包：</p>
<pre><code>pip install &lt;package&gt;==&lt;version&gt;
</code></pre>
<p>使用以下命令卸载一个第三方包：</p>
<pre><code>pip uninstall &lt;package&gt;
</code></pre>
<p>使用以下命令显示已安装第三方包的详细信息，包括版本、文档网站和作者信息：</p>
<pre><code>pip show &lt;package&gt;
</code></pre>
<h2 id="list-comprehensions-in-python">Python列表推导式</h2>
<p>列表推导式以一种非常简洁的方式创建列表。</p>
<p>假设有一个列表：</p>
<pre><code class="language-python">numbers = [1, 2, 3, 4, 5]
</code></pre>
<p>您可以使用列表推导式创建一个新列表，该列表由<code>numbers</code>列表元素的2次幂组成：</p>
<pre><code class="language-python">numbers_power_2 = [n**2 for n in numbers]
# [1, 4, 9, 16, 25]
</code></pre>
<p>列表推导是一种有时比循环更受欢迎的语法，因为当（有些）操作写在一行时其更具可读性：</p>
<pre><code class="language-python">numbers_power_2 = []
for n in numbers:
    numbers_power_2.append(n**2)
</code></pre>
<p>同样有时也比<code>map()</code>更好：</p>
<pre><code class="language-python">numbers_power_2 = list(map(lambda n : n**2, numbers))
</code></pre>
<h2 id="polymorphism-in-python">Python多态</h2>
<p>多态将一个功能泛化，因此它可以在不同的类型上工作。多态是面向对象编程中的一个重要概念。</p>
<p>我们可以在不同的类上定义相同的方法：</p>
<pre><code class="language-python">class Dog:
    def eat():
        print('Eating dog food')

class Cat:
    def eat():
        print('Eating cat food')
</code></pre>
<p>然后我们可以生成对象，无论对象属于哪个类，我们都可以调用<code>eat()</code>方法，但是会得到不同的结果：</p>
<pre><code class="language-python">animal1 = Dog()
animal2 = Cat()

animal1.eat()
animal2.eat()
</code></pre>
<p>我们构建了一个通用接口，不需要知道动物是猫还是狗。</p>
<p>译者：这个例子不太好，不完整，看下面这个例子：</p>
<pre><code class="language-python">In [1]: class Animal:
   ...:     def eat(self):
   ...:         print("animal eating ...")
   ...: 

In [2]: class Dog(Animal):
   ...:     def eat(self):
   ...:         print("dog eating ...")
   ...: 

In [3]: class Cat(Animal):
   ...:     def eat(self):
   ...:         print("cat eating ...")
   ...: 

In [4]: a = Animal()

In [5]: d = Dog()

In [6]: c = Cat()

In [7]: a.eat()
animal eating ...

In [8]: d.eat()
dog eating ...

In [9]: c.eat()
cat eating ...
</code></pre>
<p>译者：多态实际上是看运行时对象具体的类型，在Java中，是可以这样写的<code>Animal dog = new Dog()</code>，即创建一个<code>Animal</code>对象<code>dog</code>，这是<strong>编译</strong>时，但是在<strong>运行</strong>时<code>dog.eat()</code>打印<code>dog eating ...</code></p>
<h2 id="operator-overloading-in-python">Python运算符重载</h2>
<p>运算符重载是一种先进的技术，我们可以用来使类具有可比性，并使它们与Python运算符一起工作。</p>
<p>让我们来创建一个类<code>Dog</code>：</p>
<pre><code class="language-python">class Dog:
    # the Dog class
    def __init__(self, name, age):
        self.name = name
        self.age = age
</code></pre>
<p>创建两个<code>Dog</code>对象：</p>
<pre><code class="language-python">roger = Dog('Roger', 8)
syd = Dog('Syd', 7)
</code></pre>
<p>我们可以使用运算符重载添加一种基于<code>age</code>属性的方法来比较这两个对象：</p>
<pre><code class="language-python">class Dog:
    # the Dog class
    def __init__(self, name, age):
        self.name = name
        self.age = age
    def __gt__(self, other):
        return True if self.age &gt; other.age else False
</code></pre>
<p>现在如果您尝试运行<code>print(roger &gt; syd)</code>，将得到结果<code>True</code>。</p>
<p>与我们定义<code>__gt__()</code>（大于）的方式相同，我们可以定义以下方法：</p>
<ul>
<li><code>__eq__()</code> 检查是否相等</li>
<li><code>__lt__()</code> 使用<code>&lt;</code>操作符检查一个对象是否被认为低于另一个对象</li>
<li><code>__le__()</code> 表示小于或等于 (<code>&lt;=</code>)</li>
<li><code>__ge__()</code> 表示大于或等于 (<code>&gt;=</code>)</li>
<li><code>__ne__()</code> 表示不相等 (<code>!=</code>)</li>
</ul>
<p>然后还有使用算术运算符操作的方法：</p>
<ul>
<li><code>__add__()</code> 响应<code>+</code>运算符</li>
<li><code>__sub__()</code> 响应<code>-</code>运算符</li>
<li><code>__mul__()</code> 响应<code>*</code>运算符</li>
<li><code>__truediv__()</code> 响应<code>/</code>运算符</li>
<li><code>__floordiv__()</code> 响应<code>//</code>运算符</li>
<li><code>__mod__()</code> 响应<code>%</code>运算符</li>
<li><code>__pow__()</code> 响应<code>**</code>运算符</li>
<li><code>__rshift__()</code> 响应<code>&gt;&gt;</code>运算符</li>
<li><code>__lshift__()</code> 响应<code>&lt;&lt;</code>运算符</li>
<li><code>__and__()</code> 响应<code>&amp;</code>运算符</li>
<li><code>__or__()</code> 响应<code>|</code>运算符</li>
<li><code>__xor__()</code> 响应<code>^</code>运算符</li>
</ul>
<p>还有其它几种方法可以与运算符一起使用，但您应该明白了（这种思想）。</p>
<h2 id="virtual-environments-in-python">Python虚拟环境</h2>
<p>在您的系统上运行多个Python应用程序是很常见的。</p>
<p>当应用程序需要相同的模块时，有时您会遇到一个棘手的情况，即一个应用程序需要一个版本模块，而另一个应用程序需要该模块的不同版本。</p>
<p>您可以使用<strong>虚拟环境</strong>解决这个问题。</p>
<p>我们将使用<code>venv</code>。其它工具的工作方式类似，例如<code>pipenv</code>。</p>
<p>如下创建虚拟环境</p>
<pre><code class="language-sh">python -m venv .venv
</code></pre>
<p>（该命令）在您要开始的项目的文件夹或者现有项目的文件夹（的根目录下运行）。</p>
<p>译者：项目的根目录即其本身，例如一个项目fCC在<code>/Users/abc/projects/fCC</code>，那么该项目的根目录就是<code>/Users/abc/projects/fCC/</code></p>
<p>然后运行</p>
<pre><code class="language-sh">source .venv/bin/activate
</code></pre>
<blockquote>
<p>（如果是）在Fish shell上，使用 <code>source .venv/bin/activate.fish</code></p>
</blockquote>
<p>执行这个命令将激活Python虚拟环境。根据您的配置，可能还会看到终端提示发生变化。</p>
<p>我的从</p>
<p><code>➜ folder</code></p>
<p>变成</p>
<p><code>(.venv) ➜ folder</code></p>
<p>现在运行<code>pip</code>将使用这个虚拟环境而不是全局环境。</p>
<h2 id="conclusion">总结</h2>
<p>非常感谢您阅读本书。</p>
<p>我希望它能鼓励您更多去地了解 Python。</p>
<p>有关Python和一般编程教程的更多信息，请查看我的博客 <a href="https://flaviocopes.com">flaviocopes.com</a>。</p>
<p>在<a href="mailto:flavio@flaviocopes.com">mailto:flavio@flaviocopes.com</a> 发送任何反馈、勘误或意见，您可以在Twitter<a href="https://twitter.com/flaviocopes">@flaviocopes</a> 上与我联系 .</p>
<blockquote>
<p>请注意：您可以<a href="https://flaviocopes.com/page/python-handbook/">获取此Python手册的PDF、ePub和Mobi版本</a></p>
</blockquote>
<!--kg-card-end: markdown--> ]]>
                </content:encoded>
            </item>
        
    </channel>
</rss>
