python-cheatsheet

GitHub

All-inclusive Python cheatsheet

RAW Doc

Cheatsheet/Zh/Args And Kwargs

---
title: 'Python Args 和 Kwargs - Python 速查表'
description: 'args 和 kwargs 看起来可能令人畏惧,但实际上它们并不难理解,并且能赋予函数灵活性和可读性。'
labUrl: 'https://labex.io/zh/labs/python-python-args-and-kwargs-633646?course=python-cheatsheet'
---

<base-title :title="frontmatter.title" :description="frontmatter.description">
Python Args 和 Kwargs
</base-title>

<base-lab-url :url="frontmatter.labUrl" />

<base-disclaimer>
<base-disclaimer-title>
<a href="https://docs.python.org/3/tutorial/index.html">Python args and kwargs Made Easy</a>
</base-disclaimer-title>
<base-disclaimer-content>
<code>args</code> 和 <code>*kwargs</code> 可能看起来令人畏惧,但事实是它们并不难理解,并且有能力为您的函数带来极大的灵活性。
</base-disclaimer-content>
</base-disclaimer>

阅读文章 <router-link to="/blog/python-easy-args-kwargs">Python \args 和 \\*kwargs 变得简单</router-link> 以获得更深入的介绍。

Args 和 Kwargs

args*kwargs 允许您在调用函数时传递不确定数量的位置参数和关键字参数。

python

定义一个接受任意数量的位置参数和关键字参数的函数


def some_function(args, *kwargs):
pass

使用任意数量的位置参数调用


some_function(arg1, arg2, arg3)

使用任意数量的关键字参数调用


some_function(key1=arg1, key2=arg2, key3=arg3)

使用位置参数和关键字参数调用


some_function(arg, key1=arg1)

或者不带任何参数调用


some_function()

<base-warning>
<base-warning-title>
Python 惯例
</base-warning-title>
<base-warning-content>
<code>args</code> 和 <code>*kwargs</code> 是惯例。它们不是解释器强制要求的,但被 Python 社区认为是良好的实践。
</base-warning-content>
</base-warning>

args

您可以通过 args 变量访问位置参数

python

*args 将位置参数收集到一个元组中


def some_function(*args):
print(f'Arguments passed: {args} as {type(args)}')

传递多个参数 - 它们将被收集到 args 元组中


some_function('arg1', 'arg2', 'arg3')

output
Arguments passed: ('arg1', 'arg2', 'arg3') as <class 'tuple'>

<BaseQuiz id="cheatsheet-args-and-kwargs-1" correct="B">
<template #question>
<code>*args</code> 将参数收集到什么数据类型中?
</template>

<BaseQuizOption value="A">A. 列表 (A list)</BaseQuizOption>
<BaseQuizOption value="B" correct>B. 元组 (A tuple)</BaseQuizOption>
<BaseQuizOption value="C">C. 字典 (A dictionary)</BaseQuizOption>
<BaseQuizOption value="D">D. 集合 (A set)</BaseQuizOption>
<BaseQuizAnswer><code>\*args</code> 参数将位置参数收集到一个元组中。这允许函数接受任意数量的位置参数。</BaseQuizAnswer>
</BaseQuiz>

kwargs

关键字参数通过 kwargs 变量访问:

python

kwargs 将关键字参数收集到一个字典中


def some_function(kwargs):
print(f'keywords: {kwargs} as {type(kwargs)}')

传递关键字参数 - 它们将被收集到 kwargs 字典中


some_function(key1='arg1', key2='arg2')

output
keywords: {'key1': 'arg1', 'key2': 'arg2'} as <class 'dict'>

<BaseQuiz id="cheatsheet-args-and-kwargs-2" correct="C">
<template #question>
<code>kwargs</code> 将参数收集到什么数据类型中?
</template>

<BaseQuizOption value="A">A. 列表 (A list)</BaseQuizOption>
<BaseQuizOption value="B">B. 元组 (A tuple)</BaseQuizOption>
<BaseQuizOption value="C" correct>C. 字典 (A dictionary)</BaseQuizOption>
<BaseQuizOption value="D">D. 集合 (A set)</BaseQuizOption>
<BaseQuizAnswer><code>\\kwargs</code> 参数将关键字参数收集到一个字典中。这允许函数接受任意数量的关键字参数。</BaseQuizAnswer>
</BaseQuiz>

相关链接

- <router-link to="/cheatsheet/functions">函数 (Functions)</router-link>
- <router-link to="/cheatsheet/lists-and-tuples">列表和元组 (Lists and Tuples)</router-link>
- <router-link to="/cheatsheet/dictionaries">Python 字典 (Python Dictionaries)</router-link>
- <router-link to="/blog/python-easy-args-kwargs">Python \args 和 \\kwargs 变得简单 (Python \args and \\kwargs Made Easy)</router-link>
- <router-link to="/builtin/tuple">tuple()</router-link>
- <router-link to="/builtin/dict">dict()</router-link>

---

Cheatsheet/Zh/Basics

---
title: 'Python 基础 - Python 速查表'
description: '通过我们涵盖运算符、数据类型、变量、函数等的综合指南学习 Python 基础知识。非常适合初学者学习 Python 编程基础。'
labUrl: 'https://labex.io/zh/labs/python-python-basics-633647?course=python-cheatsheet'
---

<base-title :title="frontmatter.title" :description="frontmatter.description">
Python 基础知识
</base-title>

<base-lab-url :url="frontmatter.labUrl" />

我们都需要从某个地方开始,那么从这里开始怎么样呢。本指南涵盖了基本的 Python 基础知识,包括运算符、数据类型、变量和核心函数。

<base-disclaimer>
<base-disclaimer-title>
Python 基础知识概述
</base-disclaimer-title>
<base-disclaimer-content>
每个初学者都应该知道的核心 Python 基础知识:

- 变量和基本类型
- 运算符和表达式
- 字符串和常用方法
- 列表、元组和字典
- 基本控制流(if、for、while)
- 简单函数

</base-disclaimer-content>
</base-disclaimer>

数学运算符

最高最低的优先级排序:

| 运算符 | 操作 | 示例 |
| :----- | :-------- | :-------------- |
| \\ | 幂运算 | 2 3 = 8 |
| % | 取模/余数 | 22 % 8 = 6 |
| // | 整数除法 | 22 // 8 = 2 |
| / | 除法 | 22 / 8 = 2.75 |
| \ | 乘法 | 3 3 = 9 |
| - | 减法 | 5 - 2 = 3 |
| + | 加法 | 2 + 2 = 4 |

表达式示例:

python

乘法优先级高于加法


所以这被评估为:2 + (3 * 6) = 2 + 18 = 20


2 + 3 * 6

output
20

python

括号覆盖运算符优先级


这被评估为:5 * 6 = 30


(2 + 3) * 6

output
30

python
2  8

output
256

python
23 // 7

output
3

python
23 % 7

output
2

python
(5 - 1) * ((7 + 1) / (3 - 1))

output
16.0

<BaseQuiz id="cheatsheet-basics-1" correct="A">
<template #question>
这个 Python 表达式的结果是什么?

python
4 + 2 * 3

</template>

<BaseQuizOption value="A" correct>A. 10</BaseQuizOption>
<BaseQuizOption value="B">B. 18</BaseQuizOption>
<BaseQuizOption value="C">C. 12</BaseQuizOption>
<BaseQuizOption value="D">D. 20</BaseQuizOption>
<BaseQuizAnswer>乘法优先级高于加法,所以这被评估为:4 + (2 \* 3) = 4 + 6 = 10</BaseQuizAnswer>
</BaseQuiz>

增强赋值运算符

| 运算符 | 等效于 |
| :---------- | :--------------- |
| var += 1 | var = var + 1 |
| var -= 1 | var = var - 1 |
| var = 1 | var = var 1 |
| var /= 1 | var = var / 1 |
| var //= 1 | var = var // 1 |
| var %= 1 | var = var % 1 |
| var = 1 | var = var 1 |

示例:

python

增强赋值:等同于 greeting = greeting + ' world!'


greeting = 'Hello'
greeting += ' world!'
greeting

output
'Hello world!'

python

数字增 1


number = 1
number += 1
number

output
2

python

列表复制:等同于 my_list = my_list * 3


my_list = ['item']
my_list *= 3
my_list

output
['item', 'item', 'item']

<BaseQuiz id="cheatsheet-basics-2" correct="B">
<template #question>
执行此代码后 <code>x</code> 的值是多少?

python
x = 5
x += 3

</template>

<BaseQuizOption value="A">A. 3</BaseQuizOption>
<BaseQuizOption value="B" correct>B. 8</BaseQuizOption>
<BaseQuizOption value="C">C. 5</BaseQuizOption>
<BaseQuizOption value="D">D. 15</BaseQuizOption>
<BaseQuizAnswer>增强赋值运算符 <code>+=</code> 等同于 <code>x = x + 3</code>。所以 <code>x</code> 开始是 5,然后变为 5 + 3 = 8。</BaseQuizAnswer>
</BaseQuiz>

海象运算符 (Walrus Operator)

海象运算符允许在表达式中为变量赋值,同时返回该变量的值

示例:

python

海象运算符在一个表达式中赋值并返回值


my_var 被赋值为 "Hello World!" 然后被打印


print(my_var:="Hello World!")

output
Hello World!

python
my_var="Yes"
print(my_var)

output
Yes

python
print(my_var:="Hello")

output
Hello

海象运算符,或赋值表达式运算符,首次通过 PEP 572 引入于 2018 年,随后于 2019 年 10 月正式发布于 Python 3.8

<base-disclaimer>
<base-disclaimer-title>
语法语义和示例
</base-disclaimer-title>
<base-disclaimer-content>
<a href="https://peps.python.org/pep-0572/" target="_blank">PEP 572</a> 提供了海象运算符的语法、语义和示例。
</base-disclaimer-content>
</base-disclaimer>

数据类型

理解数据类型是 Python 基础知识中最重要的部分之一。Python 有九种核心内置数据类型,几乎涵盖了你需要的所有内容:

| 数据类型 | 示例 | 描述 |
| :--------------------------------------------------------- | :--------------------------------------- | :------------------- |
| 数字 (Numbers) | | |
| <router-link to='/builtin/int'>int</router-link> | -2, -1, 0, 1, 2, 3, 4, 5 | 整数 |
| <router-link to='/builtin/float'>float</router-link> | -1.25, -1.0, -0.5, 0.0, 0.5, 1.0, 1.25 | 带小数点的数字 |
| <router-link to='/builtin/complex'>complex</router-link> | 2+3j, complex(1, 4) | 具有实部和虚部的数字 |
| 文本 (Text) | | |
| <router-link to='/builtin/str'>str</router-link> | 'a', 'Hello!', "Python" | 文本和字符 |
| 布尔值 (Boolean) | | |
| <router-link to='/builtin/bool'>bool</router-link> | True, False | True 或 False 值 |
| None | | |
| NoneType | None | 表示“无值”或“空” |
| 集合 (Collections) | | |
| <router-link to='/builtin/list'>list</router-link> | [1, 2, 3], ['a', 'b', 'c'] | 有序、可更改的集合 |
| <router-link to='/builtin/dict'>dict</router-link> | {'name': 'Alice', 'age': 30} | 键值对 |
| <router-link to='/builtin/tuple'>tuple</router-link> | (1, 2, 3), ('a', 'b') | 有序、不可更改的集合 |
| <router-link to='/builtin/set'>set</router-link> | {1, 2, 3}, {'a', 'b', 'c'} | 无序的唯一项集合 |

快速示例

python

数字


age = 25 # int
price = 19.99 # float
coordinate = 2 + 3j # complex

文本


name = "Alice" # str

布尔值


is_student = True # bool

None


result = None # NoneType

集合


scores = [85, 92, 78] # list
person = {'name': 'Bob', 'age': 30} # dict
coordinates = (10, 20) # tuple
unique_ids = {1, 2, 3} # set

有关包含视觉示例和每种类型使用时机的详细说明的全面指南,请参阅:<router-link to="/blog/python-data-types">Python 数据类型:初学者的视觉指南</router-link>。

拼接和复制

字符串拼接:

python

字符串拼接:相邻的字符串会自动连接


'Alice' 'Bob'

output
'AliceBob'

字符串复制:

python

字符串复制:将字符串重复多次


'Alice' * 5

output
'AliceAliceAliceAliceAlice'

变量

变量是 Python 基础知识的一个基本组成部分。只要遵循以下规则,你可以给变量命名为任何名称:

1. 只能是一个单词。

python

错误


my variable = 'Hello'

正确


var = 'Hello'

2. 只能使用字母、数字和下划线 (_) 字符。

python

错误


%$@variable = 'Hello'

正确


my_var = 'Hello'

正确


my_var_2 = 'Hello'

3. 不能以数字开头。

python

这将不起作用


23_var = 'hello'

4. 以(单个)下划线 (_) 开头的变量被认为是“不常用的”。

python

_spam 不应在代码中再次使用


_spam = 'Hello'

<BaseQuiz id="cheatsheet-basics-3" correct="C">
<template #question>
在 Python 基础知识中,以下哪个是有效的变量名?
</template>

<BaseQuizOption value="A">A. <code>3value</code></BaseQuizOption>
<BaseQuizOption value="B">B. <code>user-name</code></BaseQuizOption>
<BaseQuizOption value="C" correct>C. <code>user_name</code></BaseQuizOption>
<BaseQuizOption value="D">D. <code>for</code></BaseQuizOption>
<BaseQuizAnswer><code>user_name</code> 是一个有效的变量名,因为它只使用字母、数字和下划线,并且不以数字开头。</BaseQuizAnswer>
</BaseQuiz>

注释

行内注释:

python

这是一个注释

多行注释:

python

这是一个


多行注释

带注释的代码:

python
a = 1  # 初始化

请注意注释前面的两个空格。

函数文档字符串 (docstring):

python
def foo():
"""
这是一个函数文档字符串
你也可以使用:
''' 函数文档字符串 '''
"""

print() 函数

print() 函数是你将学习的第一个 Python 基础知识之一。它会写入其接收到的参数的值。[...] 它处理多个参数、浮点数和字符串。字符串在打印时没有引号,并且项目之间会插入一个空格,因此你可以很好地格式化内容:

python
print('Hello world!')

output
Hello world!

python
a = 1
print('Hello world!', a)

output
Hello world! 1

end 关键字

可以使用关键字参数 end 来避免输出后的换行符,或者用不同的字符串结束输出:

python

使用 end 参数来更改每个 print 语句之后的内容


phrase = ['printed', 'with', 'a', 'dash', 'in', 'between']
for word in phrase:
print(word, end='-') # 使用 '-' 代替换行符

output
printed-with-a-dash-in-between-

sep 关键字

如果存在多个对象,关键字 sep 指定了对象之间的分隔方式:

python

使用 sep 参数指定多个参数之间的分隔符


print('cats', 'dogs', 'mice', sep=',') # 逗号分隔的输出

output
cats,dogs,mice

input() 函数

此函数从用户处获取输入并将其转换为字符串:

python

input() 读取用户输入并将其作为字符串返回


print('What is your name?') # 询问他们的名字
my_name = input() # 等待用户输入并按 Enter
print('Hi, {}'.format(my_name))

output
What is your name?
Martha
Hi, Martha

input() 也可以在不使用 print() 的情况下设置默认消息:

python
my_name = input('What is your name? ')  # 默认消息
print('Hi, {}'.format(my_name))

output
What is your name? Martha
Hi, Martha

也可以使用格式化字符串来避免使用 .format:

python

input() 可以直接显示提示信息


my_name = input('What is your name? ') # 提示和读取在一次调用中完成
print(f'Hi, {my_name}') # f-string 用于字符串格式化

output
What is your name? Martha
Hi, Martha

<BaseQuiz id="cheatsheet-basics-4" correct="B">
<template #question>
在 Python 基础知识中,input() 返回什么类型?
</template>

<BaseQuizOption value="A">A. int</BaseQuizOption>
<BaseQuizOption value="B" correct>B. str</BaseQuizOption>
<BaseQuizOption value="C">C. float</BaseQuizOption>
<BaseQuizOption value="D">D. 取决于用户输入</BaseQuizOption>
<BaseQuizAnswer><code>input()</code> 函数总是返回一个字符串,无论用户输入什么。如果需要,你需要将其转换为其他类型。</BaseQuizAnswer>
</BaseQuiz>

len() 函数

评估字符串、列表、字典等的字符数或项目数的整数值:

python

len() 返回字符串中的字符数


len('hello') # 返回 5

output
5

python

len() 返回列表中项目的数量


len(['cat', 3, 'dog']) # 返回 3 (三个项目)

output
3

<base-warning>
<base-warning-title>空值测试</base-warning-title>
<base-warning-content>
对字符串、列表、字典等的空值测试不应使用
<code>len</code>,而应优先使用直接的布尔值评估。
</base-warning-content>
</base-warning>

空值测试示例:

python
a = [1, 2, 3]

错误:不必要的 len() 检查


if len(a) > 0: # 评估为 True
print("the list is not empty!")

output
the list is not empty!

python

正确:直接布尔评估 (Pythonic 方式)


if a: # 如果列表不为空,则评估为 True
print("the list is not empty!")

output
the list is not empty!

str()、int() 和 float() 函数

这些函数允许你更改变量的类型。例如,你可以将 integerfloat 转换为 string

python

整数转字符串


str(29) # 返回 '29'

output
'29'

python
str(-3.14)

output
'-3.14'

或者从 string 转换为 integerfloat

python

字符串转整数


int('11') # 返回 11

output
11

python

字符串转浮点数


float('3.14') # 返回 3.14

output
3.14

<BaseQuiz id="cheatsheet-basics-5" correct="C">
<template #question>
这段 Python 代码的结果是什么?

python
result = int('42')
type(result)

</template>

<BaseQuizOption value="A">A. <code>str</code></BaseQuizOption>
<BaseQuizOption value="B">B. <code>float</code></BaseQuizOption>
<BaseQuizOption value="C" correct>C. <code>int</code></BaseQuizOption>
<BaseQuizOption value="D">D. <code>NoneType</code></BaseQuizOption>
<BaseQuizAnswer><code>int()</code> 函数将字符串转换为整数。因此 <code>int('42')</code> 返回整数 <code>42</code>,而 <code>type(42)</code> 返回 <code>int</code>。</BaseQuizAnswer>
</BaseQuiz>

相关链接

- <router-link to="/blog/python-data-types">Python 数据类型:初学者的视觉指南</router-link>
- <router-link to="/blog/python-comprehensions-step-by-step">Python 推导式分步指南</router-link>
- <router-link to="/cheatsheet/control-flow">控制流</router-link>
- <router-link to="/cheatsheet/functions">函数</router-link>
- <router-link to="/cheatsheet/lists-and-tuples">列表和元组</router-link>
- <router-link to="/cheatsheet/dictionaries">字典</router-link>
- <router-link to="/cheatsheet/sets">集合</router-link>
- <router-link to="/cheatsheet/string-formatting">字符串格式化</router-link>

---

Cheatsheet/Zh/Built In Functions

---
title: 'Python 内置函数 - Python 速查表'
description: 'Python 解释器内置了许多始终可用的函数和类型。'
labUrl: 'https://labex.io/zh/labs/python-python-built-in-functions-633648?course=python-cheatsheet'
---

<base-title :title="frontmatter.title" :description="frontmatter.description">
Python 内置函数
</base-title>

<base-lab-url :url="frontmatter.labUrl" />

Python 解释器内置了许多函数和类型,它们始终可用。

Python 内置函数

| 函数 | 描述 |
| :------------------------------------------------------------------- | :---------------------------------------------------- |
| <router-link to='/builtin/abs'>abs()</router-link> | 返回数字的绝对值。 |
| <router-link to='/builtin/aiter'>aiter()</router-link> | 返回异步可迭代对象的异步迭代器。 |
| <router-link to='/builtin/all'>all()</router-link> | 如果可迭代对象中的所有元素都为 True,则返回 True。 |
| <router-link to='/builtin/any'>any()</router-link> | 如果可迭代对象中的任何元素为 True,则返回 True。 |
| <router-link to='/builtin/ascii'>ascii()</router-link> | 返回对象的“可打印”表示的字符串。 |
| <router-link to='/builtin/bin'>bin()</router-link> | 将整数转换为二进制字符串。 |
| <router-link to='/builtin/bool'>bool()</router-link> | 返回一个布尔值。 |
| <router-link to='/builtin/breakpoint'>breakpoint()</router-link> | 在调用站点将您置于调试器中。 |
| <router-link to='/builtin/bytearray'>bytearray()</router-link> | 返回一个新的字节数组。 |
| <router-link to='/builtin/bytes'>bytes()</router-link> | 返回一个新的“bytes”对象。 |
| <router-link to='/builtin/callable'>callable()</router-link> | 如果对象参数是可调用的,则返回 True,否则返回 False。 |
| <router-link to='/builtin/chr'>chr()</router-link> | 返回表示单个字符的字符串。 |
| <router-link to='/builtin/classmethod'>classmethod()</router-link> | 将方法转换为类方法。 |
| <router-link to='/builtin/compile'>compile()</router-link> | 将源代码编译成代码对象或 AST 对象。 |
| <router-link to='/builtin/complex'>complex()</router-link> | 返回一个值为 real + imag\*1j 的复数。 |
| <router-link to='/builtin/delattr'>delattr()</router-link> | 删除命名属性,前提是对象允许这样做。 |
| <router-link to='/builtin/dict'>dict()</router-link> | 创建一个新的字典。 |
| <router-link to='/builtin/dir'>dir()</router-link> | 返回当前局部作用域中的名称列表。 |
| <router-link to='/builtin/divmod'>divmod()</router-link> | 返回一个包含商和余数的数对。 |
| <router-link to='/builtin/enumerate'>enumerate()</router-link> | 返回一个枚举对象。 |
| <router-link to='/builtin/eval'>eval()</router-link> | 评估并执行一个表达式。 |
| <router-link to='/builtin/exec'>exec()</router-link> | 此函数支持 Python 代码的动态执行。 |
| <router-link to='/builtin/filter'>filter()</router-link> | 从可迭代对象构造一个迭代器,并返回使函数为真的元素。 |
| <router-link to='/builtin/float'>float()</router-link> | 从数字或字符串返回一个浮点数。 |
| <router-link to='/builtin/format'>format()</router-link> | 将值转换为“格式化”的表示。 |
| <router-link to='/builtin/frozenset'>frozenset()</router-link> | 返回一个新的冻结集合对象。 |
| <router-link to='/builtin/getattr'>getattr()</router-link> | 返回对象命名属性的值。 |
| <router-link to='/builtin/globals'>globals()</router-link> | 返回实现当前模块命名空间的字典。 |
| <router-link to='/builtin/hasattr'>hasattr()</router-link> | 如果对象具有命名属性,则返回 True。 |
| <router-link to='/builtin/hash'>hash()</router-link> | 返回对象的哈希值。 |
| <router-link to='/builtin/help'>help()</router-link> | 调用内置帮助系统。 |
| <router-link to='/builtin/hex'>hex()</router-link> | 将整数转换为小写十六进制字符串。 |
| <router-link to='/builtin/id'>id()</router-link> | 返回对象的“身份”。 |
| <router-link to='/builtin/input'>input()</router-link> | 此函数接受输入并将其转换为字符串。 |
| <router-link to='/builtin/int'>int()</router-link> | 从数字或字符串返回一个整数对象。 |
| <router-link to='/builtin/isinstance'>isinstance()</router-link> | 如果对象参数是对象的一个实例,则返回 True。 |
| <router-link to='/builtin/issubclass'>issubclass()</router-link> | 如果 class 是 classinfo 的子类,则返回 True。 |
| <router-link to='/builtin/iter'>iter()</router-link> | 返回一个迭代器对象。 |
| <router-link to='/builtin/len'>len()</router-link> | 返回对象的长度(项目数)。 |
| <router-link to='/builtin/list'>list()</router-link> | 实际上是一个可变序列类型,而不是函数。 |
| <router-link to='/builtin/locals'>locals()</router-link> | 更新并返回包含当前局部符号表的字典。 |
| <router-link to='/builtin/map'>map()</router-link> | 返回一个迭代器,将函数应用于可迭代对象的每个项目。 |
| <router-link to='/builtin/max'>max()</router-link> | 返回可迭代对象中最大的项。 |
| <router-link to='/builtin/min'>min()</router-link> | 返回可迭代对象中最小的项。 |
| <router-link to='/builtin/next'>next()</router-link> | 从迭代器中检索下一个项。 |
| <router-link to='/builtin/object'>object()</router-link> | 返回一个新的无特征对象。 |
| <router-link to='/builtin/oct'>oct()</router-link> | 将整数转换为八进制字符串。 |
| <router-link to='/builtin/open'>open()</router-link> | 打开文件并返回相应的文件对象。 |
| <router-link to='/builtin/ord'>ord()</router-link> | 返回表示单个字符的 Unicode 码点的整数。 |
| <router-link to='/builtin/pow'>pow()</router-link> | 返回 base 的 exp 次方。 |
| <router-link to='/builtin/print'>print()</router-link> | 将对象打印到文本流文件。 |
| <router-link to='/builtin/property'>property()</router-link> | 返回一个属性对象。 |
| <router-link to='/builtin/repr'>repr()</router-link> | 返回对象的“可打印”字符串表示形式。 |
| <router-link to='/builtin/reversed'>reversed()</router-link> | 返回一个反向迭代器。 |
| <router-link to='/builtin/round'>round()</router-link> | 返回数字四舍五入到小数点后 ndigits 位的结果。 |
| <router-link to='/builtin/set'>set()</router-link> | 返回一个新的集合对象。 |
| <router-link to='/builtin/setattr'>setattr()</router-link> | 这是 getattr() 的对应函数。 |
| <router-link to='/builtin/slice'>slice()</router-link> | 返回一个表示一组索引的切片对象。 |
| <router-link to='/builtin/sorted'>sorted()</router-link> | 从可迭代对象的项返回一个新排序的列表。 |
| <router-link to='/builtin/staticmethod'>staticmethod()</router-link> | 将方法转换为静态方法。 |
| <router-link to='/builtin/str'>str()</router-link> | 返回对象的 str 版本。 |
| <router-link to='/builtin/sum'>sum()</router-link> | 对 start 和可迭代对象的项求和。 |
| <router-link to='/builtin/super'>super()</router-link> | 返回一个代理对象,将方法调用委托给父类或同级类。 |
| <router-link to='/builtin/tuple'>tuple()</router-link> | 实际上是一个不可变序列类型,而不是函数。 |
| <router-link to='/builtin/type'>type()</router-link> | 返回对象的类型。 |
| <router-link to='/builtin/vars'>vars()</router-link> | 返回任何其他具有 dict 属性的对象的 dict 属性。 |
| <router-link to='/builtin/zip'>zip()</router-link> | 对多个可迭代对象进行并行迭代。 |
| <router-link to='/builtin/import'>import()</router-link> | 此函数由 import 语句调用。 |

---

Cheatsheet/Zh/Comprehensions

---
title: 'Python 列表推导式 - Python 速查表'
description: '列表推导式提供了一种简洁的创建列表的方法'
labUrl: 'https://labex.io/zh/labs/python-python-comprehensions-633649?course=python-cheatsheet'
---

<base-title :title="frontmatter.title" :description="frontmatter.description">
Python 列表推导式
</base-title>

<base-lab-url :url="frontmatter.labUrl" />

列表推导式 (List Comprehensions) 是一种特殊的语法,它允许我们从其他列表中创建列表,在处理数字和包含一到两个嵌套 for 循环时非常有用。

<base-disclaimer>
<base-disclaimer-title>
摘自 Python 3 <a target="_blank" href="https://docs.python.org/3/tutorial/datastructures.html#list-comprehensions">教程</a>
</base-disclaimer-title>
<base-disclaimer-content>
列表推导式提供了一种简洁的方式来创建列表。 [...] 或者创建满足特定条件的数据子序列。
</base-disclaimer-content>
</base-disclaimer>

阅读 <router-link to="/blog/python-comprehensions-step-by-step">Python 列表推导式:分步介绍</router-link> 以获得更深入的介绍。

列表推导式

这是我们使用 For 循环从现有集合创建新列表的方式:

python

传统方法:使用 for 循环创建列表


names = ['Charles', 'Susan', 'Patrick', 'George']

new_list = []
for n in names:
new_list.append(n)

new_list

output
['Charles', 'Susan', 'Patrick', 'George']

这是我们使用列表推导式完成相同操作的方式:

python

列表推导式:创建新列表的简洁方式


语法:[expression for item in iterable]


names = ['Charles', 'Susan', 'Patrick', 'George']

new_list = [n for n in names] # 创建包含所有名字的列表
new_list

output
['Charles', 'Susan', 'Patrick', 'George']

<BaseQuiz id="cheatsheet-comprehensions-1" correct="A">
<template #question>
列表推导式的基本语法是什么?
</template>

<BaseQuizOption value="A" correct>A. <code>[expression for item in iterable]</code></BaseQuizOption>
<BaseQuizOption value="B">B. <code>(expression for item in iterable)</code></BaseQuizOption>
<BaseQuizOption value="C">C. <code>{expression for item in iterable}</code></BaseQuizOption>
<BaseQuizOption value="D">D. <code>expression for item in iterable</code></BaseQuizOption>
<BaseQuizAnswer>列表推导式使用方括号 <code>[]</code> 和语法 <code>[expression for item in iterable]</code>。它通过对每个项目应用表达式来创建一个新列表。</BaseQuizAnswer>
</BaseQuiz>

我们可以对数字做同样的事情:

python

嵌套列表推导式:从两个范围创建元组


等同于嵌套的 for 循环


n = [(a, b) for a in range(1, 3) for b in range(1, 3)]
n

output
[(1, 1), (1, 2), (2, 1), (2, 2)]

添加条件判断

如果我们想让 new_list 只包含以 C 开头的名字,使用 for 循环,我们会这样做:

python

传统方法:使用 if 条件进行过滤


names = ['Charles', 'Susan', 'Patrick', 'George', 'Carol']

new_list = []
for n in names:
if n.startswith('C'): # 过滤以 'C' 开头的名字
new_list.append(n)

print(new_list)

output
['Charles', 'Carol']

在列表推导式中,我们将 if 语句放在末尾:

python

带条件的列表推导式:过滤项目


语法:[expression for item in iterable if condition]


new_list = [n for n in names if n.startswith('C')]
print(new_list)

output
['Charles', 'Carol']

<BaseQuiz id="cheatsheet-comprehensions-2" correct="B">
<template #question>
列表推导式中的 <code>if</code> 条件放在哪里?
</template>

<BaseQuizOption value="A">A. 在 <code>for</code> 关键字之前</BaseQuizOption>
<BaseQuizOption value="B" correct>B. 在 <code>for</code> 子句之后</BaseQuizOption>
<BaseQuizOption value="C">C. 在表达式内部</BaseQuizOption>
<BaseQuizOption value="D">D. 在方括号之前</BaseQuizOption>
<BaseQuizAnswer>在列表推导式中,<code>if</code> 条件位于 <code>for</code> 子句之后:<code>[expression for item in iterable if condition]</code>。这会根据条件过滤项目。</BaseQuizAnswer>
</BaseQuiz>

要在列表推导式中使用 if-else 语句:

python

带 if-else 的列表推导式:条件表达式


语法:[expression_if_true if condition else expression_if_false for item in iterable]


nums = [1, 2, 3, 4, 5, 6]
new_list = [num*2 if num % 2 == 0 else num for num in nums] # 将偶数翻倍
print(new_list)

output
[1, 4, 3, 8, 5, 12]

<base-disclaimer>
<base-disclaimer-title>
集合和字典推导式
</base-disclaimer-title>
<base-disclaimer-content>
list 推导式的基础知识也适用于 <b>集合</b> (sets) 和 <b>字典</b> (dictionaries)。
</base-disclaimer-content>
</base-disclaimer>

集合推导式

python

集合推导式:使用推导式语法创建集合


语法:{expression for item in iterable}


b = {"abc", "def"}
{s.upper() for s in b} # 将所有字符串转换为大写

output
{"ABC", "DEF"}

字典推导式

python

字典推导式:交换键和值


语法:{key_expression: value_expression for item in iterable}


c = {'name': 'Pooka', 'age': 5}
{v: k for k, v in c.items()} # 反转键值对

output
{'Pooka': 'name', 5: 'age'}

<BaseQuiz id="cheatsheet-comprehensions-3" correct="C">
<template #question>
字典推导式使用什么语法?
</template>

<BaseQuizOption value="A">A. <code>[key: value for item in iterable]</code></BaseQuizOption>
<BaseQuizOption value="B">B. <code>(key: value for item in iterable)</code></BaseQuizOption>
<BaseQuizOption value="C" correct>C. <code>{key_expression: value_expression for item in iterable}</code></BaseQuizOption>
<BaseQuizOption value="D">D. <code>{key, value for item in iterable}</code></BaseQuizOption>
<BaseQuizAnswer>字典推导式使用花括号 <code>{}</code> 和语法 <code>{key_expression: value_expression for item in iterable}</code>,类似于列表推导式,但包含键值对。</BaseQuizAnswer>
</BaseQuiz>

列表推导式可以从字典生成:

python

从字典创建列表推导式:创建格式化的字符串


c = {'name': 'Pooka', 'age': 5}
["{}:{}".format(k.upper(), v) for k, v in c.items()] # 格式化为 "KEY:value"

output
['NAME:Pooka', 'AGE:5']

相关链接

- <router-link to="/blog/python-comprehensions-step-by-step">Python 列表推导式:分步介绍</router-link>
- <router-link to="/cheatsheet/lists-and-tuples">Python 列表和元组</router-link>
- <router-link to="/cheatsheet/sets">Python 集合</router-link>
- <router-link to="/cheatsheet/dictionaries">Python 字典</router-link>
- <router-link to="/blog/python-sets-what-why-how">Python 集合:是什么、为什么以及如何使用</router-link>
- <router-link to="/blog/python-data-types">Python 数据类型博客文章</router-link>

---

Cheatsheet/Zh/Context Manager

---
title: 'Python 上下文管理器 - Python 速查表'
description: 'Python 上下文管理器用途广泛,但很少有人真正理解其背后的目的。这些语句常用于文件读写,通过确保特定资源仅在特定进程中使用,帮助应用程序节省系统内存并改善资源管理。'
labUrl: 'https://labex.io/zh/labs/python-python-context-manager-633650?course=python-cheatsheet'
---

<base-title :title="frontmatter.title" :description="frontmatter.description">
Python 上下文管理器
</base-title>

<base-lab-url :url="frontmatter.labUrl" />

虽然 Python 的上下文管理器被广泛使用,但很少有人理解其背后的目的。这些语句通常用于读写文件,通过确保特定资源仅在特定进程中使用,来帮助应用程序节省系统内存并改进资源管理。

with 语句

上下文管理器是一个对象,它在上下文(一段代码块)开始和结束时会收到通知。你通常使用 with 语句来使用它。它负责处理通知。

例如,文件对象就是上下文管理器。当上下文结束时,文件对象会自动关闭:

python

上下文管理器:自动处理资源清理


退出 'with' 块时文件自动关闭


with open(filename) as f: # 'f' 是文件对象
file_contents = f.read()

即使发生错误,文件也会在此处自动关闭

<BaseQuiz id="cheatsheet-context-manager-1" correct="A">
<template #question>
使用上下文管理器(<code>with</code> 语句)的主要好处是什么?
</template>

<BaseQuizOption value="A" correct>A. 自动处理资源清理,即使发生错误</BaseQuizOption>
<BaseQuizOption value="B">B. 使代码执行速度更快</BaseQuizOption>
<BaseQuizOption value="C">C. 允许多个文件同时打开</BaseQuizOption>
<BaseQuizOption value="D">D. 阻止所有错误</BaseQuizOption>
<BaseQuizAnswer>上下文管理器确保资源(如文件)在退出代码块时得到妥善清理,即使发生异常也是如此。这可以防止资源泄漏和数据丢失。</BaseQuizAnswer>
</BaseQuiz>

任何导致代码块执行结束的操作都会导致调用上下文管理器的退出方法。这包括异常,当错误导致你过早地退出一个打开的文件或连接时,这会很有用。在没有正确关闭文件/连接的情况下退出脚本是个坏主意,可能会导致数据丢失或其他问题。通过使用上下文管理器,你可以确保始终采取预防措施以防止以这种方式造成损害或损失。

编写你自己的上下文管理器

也可以使用生成器语法来编写上下文管理器,这要归功于 contextlib.contextmanager 装饰器:

python

使用 contextlib 装饰器的基于函数的上下文管理器


import contextlib
@contextlib.contextmanager
def context_manager(num):
print('Enter') # yield 之前的代码在 __enter__ 上运行
yield num + 1 # yield 的值成为 'cm' 变量
print('Exit') # yield 之后代码在 __exit__ 上运行

with context_manager(2) as cm: # cm 接收 yield 的值 (3)
print('Right in the middle with cm = {}'.format(cm))

output
Enter
Right in the middle with cm = 3
Exit

基于类的上下文管理器

你可以定义基于类的上下文管理器。关键方法是 __enter____exit__

python

基于类的上下文管理器:实现 __enter__ 和 __exit__ 方法


class ContextManager:
def __enter__(self, args, *kwargs): # 进入 'with' 块时调用
print("--enter--")
return self # 可以返回对象用作 'as' 变量

def __exit__(self, *args): # 退出 'with' 块时调用
print("--exit--")

with ContextManager(): # 调用 __enter__,完成后调用 __exit__
print("test")

output
--enter--
test
--exit--

<BaseQuiz id="cheatsheet-context-manager-2" correct="B">
<template #question>
一个类要用作上下文管理器,必须实现哪些方法?
</template>

<BaseQuizOption value="A">A. <code>init</code> 和 <code>del</code></BaseQuizOption>
<BaseQuizOption value="B" correct>B. <code>enter</code> 和 <code>exit</code></BaseQuizOption>
<BaseQuizOption value="C">C. <code>open</code> 和 <code>close</code></BaseQuizOption>
<BaseQuizOption value="D">D. <code>start</code> 和 <code>stop</code></BaseQuizOption>
<BaseQuizAnswer>基于类的上下文管理器必须实现 <code>enter</code>(在进入 <code>with</code> 块时调用)和 <code>exit</code>(在退出该块时调用)。</BaseQuizAnswer>
</BaseQuiz>

相关链接

- <router-link to="/cheatsheet/reading-and-writing-files">读写文件</router-link>
- <router-link to="/cheatsheet/exception-handling">异常处理</router-link>
- <router-link to="/cheatsheet/decorators">装饰器</router-link>
- <router-link to="/blog/python-pathlib-essentials">每位开发者都应知道的 10 个基本文件系统操作</router-link>
- <router-link to="/builtin/open">open()</router-link>

---

Cheatsheet/Zh/Control Flow

---
title: 'Python 控制流 - Python 速查表'
description: '控制流是单个语句、指令或函数调用执行或评估的顺序。Python 程序的控制流由条件语句、循环和函数调用来调节。'
labUrl: 'https://labex.io/zh/labs/python-python-control-flow-633651?course=python-cheatsheet'
---

<base-title :title="frontmatter.title" :description="frontmatter.description">
Python 控制流
</base-title>

<base-lab-url :url="frontmatter.labUrl" />

<base-disclaimer>
<base-disclaimer-title>
Python 控制流
</base-disclaimer-title>
<base-disclaimer-content>
控制流是单个语句、指令或函数调用被执行或求值的顺序。Python 程序的控制流由条件语句、循环和函数调用来调节。
</base-disclaimer-content>
</base-disclaimer>

比较运算符

| 运算符 | 含义 |
| ------ | ---------- |
| == | 等于 |
| != | 不等于 |
| < | 小于 |
| > | 大于 |
| <= | 小于或等于 |
| >= | 大于或等于 |

这些运算符根据你给它们的值评估为 True 或 False。

示例:

python
42 == 42

output
True

python
40 == 42

output
False

python
'hello' == 'hello'

output
True

python
'hello' == 'Hello'

output
False

python
'dog' != 'cat'

output
True

python
42 == 42.0

output
True

python
42 == '42'

output
False

<BaseQuiz id="cheatsheet-control-flow-1" correct="B">
<template #question>
<code>'hello' == 'Hello'</code> 的评估结果是什么?
</template>

<BaseQuizOption value="A">A. <code>True</code></BaseQuizOption>
<BaseQuizOption value="B" correct>B. <code>False</code></BaseQuizOption>
<BaseQuizOption value="C">C. <code>None</code></BaseQuizOption>
<BaseQuizOption value="D">D. 抛出错误</BaseQuizOption>
<BaseQuizAnswer>Python 中的字符串比较是区分大小写的。<code>'hello'</code> 和 <code>'Hello'</code> 是不同的字符串,因此比较结果为 <code>False</code>。</BaseQuizAnswer>
</BaseQuiz>

布尔运算符

有三个布尔运算符:andornot
按优先级从高到低依次是 notandor

and 运算符的真值表

| 表达式 | 评估结果 |
| ----------------- | -------- |
| True and True | True |
| True and False | False |
| False and True | False |
| False and False | False |

or 运算符的真值表

| 表达式 | 评估结果 |
| ---------------- | -------- |
| True or True | True |
| True or False | True |
| False or True | True |
| False or False | False |

not 运算符的真值表

| 表达式 | 评估结果 |
| ----------- | -------- |
| not True | False |
| not False | True |

混合运算符

你可以混合使用布尔运算符和比较运算符:

python
(4 < 5) and (5 < 6)

output
True

python
(4 < 5) and (9 < 6)

output
False

python
(1 == 2) or (2 == 2)

output
True

此外,你可以在一个表达式中混合使用多个布尔运算符以及比较运算符:

python
2 + 2 == 4 and not 2 + 2 == 5 and 2 * 2 == 2 + 2

output
True

python

在下面的语句中,3 < 4 and 5 > 5 首先被执行,评估为 False


然后 5 > 4 返回 True,所以 True or False 的结果是 True


5 > 4 or 3 < 4 and 5 > 5

output
True

python

现在括号内的语句首先被执行,所以 True and False 返回 False。


(5 > 4 or 3 < 4) and 5 > 5

output
False

if 语句

if 语句评估一个表达式,如果该表达式为 True,则执行接下来的缩进代码:

python

if 语句:当条件为 True 时执行代码块


name = 'Debora'

if name == 'Debora': # 检查 name 是否等于 'Debora'
print('Hi, Debora') # 如果条件为 True,则执行此行

output
Hi, Debora

python
if name != 'George':
print('You are not George')

output
You are not George

只有当 if 和所有 elif 表达式的评估结果都为 False 时,else 语句才会执行:

python

if-else:根据条件执行不同的代码


name = 'Debora'

if name == 'George':
print('Hi, George.')
else: # 如果 if 条件为 False,则执行
print('You are not George')

output
You are not George

<BaseQuiz id="cheatsheet-control-flow-2" correct="B">
<template #question>
在 if-else 语句中,<code>else</code> 块何时执行?
</template>

<BaseQuizOption value="A">A. 总是</BaseQuizOption>
<BaseQuizOption value="B" correct>B. 仅当 <code>if</code> 条件(以及所有 <code>elif</code> 条件(如果存在))为 <code>False</code> 时</BaseQuizOption>
<BaseQuizOption value="C">C. 仅当 <code>if</code> 条件为 <code>True</code> 时</BaseQuizOption>
<BaseQuizOption value="D">D. 从不</BaseQuizOption>
<BaseQuizAnswer>只有当 <code>if</code> 条件和所有 <code>elif</code> 条件(如果存在)都评估为 <code>False</code> 时,<code>else</code> 块才会执行。</BaseQuizAnswer>
</BaseQuiz>

只有在 if 语句的表达式为 False 之后,才会评估并执行 elif 语句:

python

if-elif:按顺序检查多个条件


name = 'George'

if name == 'Debora':
print('Hi Debora!')
elif name == 'George': # 仅在前一个条件为 False 时检查
print('Hi George!')

output
Hi George!

elifelse 部分是可选的。

python
name = 'Antony'

if name == 'Debora':
print('Hi Debora!')
elif name == 'George':
print('Hi George!')
else:
print('Who are you?')

output
Who are you?

三元条件运算符

许多编程语言都有一个三元运算符,用于定义条件表达式。最常见的用法是创建一个简洁的简单条件赋值语句。换句话说,如果条件为真,它提供单行代码来评估第一个表达式,否则评估第二个表达式。

plaintext
<expression1> if <condition> else <expression2>

示例:

python
age = 15

这个 if 语句:


if age < 18:
print('kid')
else:
print('adult')

output
kid

python

三元运算符:单行条件表达式


语法:value_if_true if condition else value_if_false


print('kid' if age < 18 else 'adult')

output
kid

三元运算符可以链式使用:

python
age = 15

这个三元运算符:


print('kid' if age < 13 else 'teen' if age < 18 else 'adult')

output
teen

python

等同于这个 if 语句:


if age < 13:
print('kid')
else:
if age < 18:
print('teen')
else:
print('adult')

output
teen

Switch-Case 语句

<base-disclaimer>
<base-disclaimer-title>
Switch-Case 语句
</base-disclaimer-title>
<base-disclaimer-content>
在计算机编程语言中,switch 语句是一种选择控制机制,用于通过搜索和映射来允许变量或表达式的值改变程序的控制流执行。
</base-disclaimer-content>
</base-disclaimer>

_Switch-Case 语句_,或结构化模式匹配,首次通过 PEP 622 引入于 2020 年,并于 2022 年 9 月随 Python 3.10 正式发布。

<base-disclaimer>
<base-disclaimer-title>
官方教程
</base-disclaimer-title>
<base-disclaimer-content>
<a href="https://peps.python.org/pep-0636/" target="_blank">PEP 636</a> 为 Python 模式匹配或 Switch-Case 语句提供了官方教程。
</base-disclaimer-content>
</base-disclaimer>

匹配单个值

python
response_code = 201
match response_code:
case 200:
print("OK")
case 201:
print("Created")
case 300:
print("Multiple Choices")
case 307:
print("Temporary Redirect")
case 404:
print("404 Not Found")
case 500:
print("Internal Server Error")
case 502:
print("502 Bad Gateway")

output
Created

使用 or 模式匹配

在此示例中,管道字符 (|or) 允许 Python 为两个或多个情况返回相同的响应。

python
response_code = 502
match response_code:
case 200 | 201:
print("OK")
case 300 | 307:
print("Redirect")
case 400 | 401:
print("Bad Request")
case 500 | 502:
print("Internal Server Error")

output
Internal Server Error

按可迭代对象的长度匹配

python
today_responses = [200, 300, 404, 500]
match today_responses:
case [a]:
print(f"One response today: {a}")
case [a, b]:
print(f"Two responses today: {a} and {b}")
case [a, b, *rest]:
print(f"All responses: {a}, {b}, {rest}")

output
All responses: 200, 300, [404, 500]

默认值

下划线符号 (_) 用于定义默认情况:

python
response_code = 800
match response_code:
case 200 | 201:
print("OK")
case 300 | 307:
print("Redirect")
case 400 | 401:
print("Bad Request")
case 500 | 502:
print("Internal Server Error")
case _:
print("Invalid Code")

output
Invalid Code

匹配内置类

python
response_code = "300"
match response_code:
case int():
print('Code is a number')
case str():
print('Code is a string')
case _:
print('Code is neither a string nor a number')

output
Code is a string

保护 Match-Case 语句

python
response_code = 300
match response_code:
case int() if response_code > 99 and response_code < 500:
print('Code is a valid number')
case _:
print('Code is an invalid number')

output
Code is a valid number

while 循环语句

while 语句用于重复执行,只要一个表达式为 True

python

while 循环:只要条件为 True,就重复执行代码


spam = 0
while spam < 5: # 只要 spam 小于 5 就继续
print('Hello, world.')
spam = spam + 1 # 增加计数器以避免无限循环

output
Hello, world.
Hello, world.
Hello, world.
Hello, world.
Hello, world.

<BaseQuiz id="cheatsheet-control-flow-3" correct="A">
<template #question>
<code>while</code> 循环做什么?
</template>

<BaseQuizOption value="A" correct>A. 只要条件为 <code>True</code> 就重复执行代码</BaseQuizOption>
<BaseQuizOption value="B">B. 只执行代码一次</BaseQuizOption>
<BaseQuizOption value="C">C. 执行固定次数的代码</BaseQuizOption>
<BaseQuizOption value="D">D. 跳过代码执行</BaseQuizOption>
<BaseQuizAnswer><code>while</code> 循环只要条件评估为 <code>True</code> 就重复执行一段代码。当条件变为 <code>False</code> 时,循环停止。</BaseQuizAnswer>
</BaseQuiz>

break 语句

如果执行到达 break 语句,它会立即退出 while 循环的子句:

python

break 语句:遇到时立即退出循环


while True: # 无限循环
name = input('Please type your name: ')
if name == 'your name':
break # 立即退出循环

print('Thank you!')

output
Please type your name: your name
Thank you!

continue 语句

当程序执行到达 continue 语句时,程序执行立即跳回到循环的开头。

python

continue 语句:跳过循环迭代的其余部分并开始下一次迭代


while True:
name = input('Who are you? ')
if name != 'Joe':
continue # 跳到下一次迭代,不询问密码
password = input('Password? (It is a fish.): ')
if password == 'swordfish':
break # 密码正确时退出循环

print('Access granted.')

output
Who are you? Charles
Who are you? Debora
Who are you? Joe
Password? (It is a fish.): swordfish
Access granted.

For 循环

for 循环迭代 listtupledictionarysetstring

python

for 循环:迭代序列中的每个项目


pets = ['Bella', 'Milo', 'Loki']
for pet in pets: # 循环遍历列表中的每只宠物
print(pet) # 打印每只宠物的名字

output
Bella
Milo
Loki

<BaseQuiz id="cheatsheet-control-flow-4" correct="C">
<template #question>
<code>for</code> 循环迭代什么?
</template>

<BaseQuizOption value="A">A. 仅数字</BaseQuizOption>
<BaseQuizOption value="B">B. 仅字符串</BaseQuizOption>
<BaseQuizOption value="C" correct>C. 任何可迭代序列(列表、元组、字典、集合、字符串等)</BaseQuizOption>
<BaseQuizOption value="D">D. 仅列表</BaseQuizOption>
<BaseQuizAnswer><code>for</code> 循环可以迭代任何可迭代序列,包括列表、元组、字典、集合、字符串和其他可迭代对象。</BaseQuizAnswer>
</BaseQuiz>

range() 函数

range() 函数返回一个数字序列。它从 0 开始,以 1 递增,并在指定的数字之前停止:

python
for i in range(5):
print(f'Will stop at 5! or 4? ({i})')

output
Will stop at 5! or 4? (0)
Will stop at 5! or 4? (1)
Will stop at 5! or 4? (2)
Will stop at 5! or 4? (3)
Will stop at 5! or 4? (4)

<BaseQuiz id="cheatsheet-control-flow-5" correct="B">
<template #question>
<code>range(5)</code> 生成什么?
</template>

<BaseQuizOption value="A">A. 从 1 到 5 的数字</BaseQuizOption>
<BaseQuizOption value="B" correct>B. 从 0 到 4 的数字</BaseQuizOption>
<BaseQuizOption value="C">C. 从 0 到 5 的数字</BaseQuizOption>
<BaseQuizOption value="D">D. 五个随机数</BaseQuizOption>
<BaseQuizAnswer><code>range(5)</code> 函数生成从 0 到 4 的数字(共 5 个数字)。停止值是排他的,因此它在到达 5 之前停止。</BaseQuizAnswer>
</BaseQuiz>

range() 函数也可以修改其 3 个默认参数。前两个是 startstop 值,第三个是 step 参数。step 是每次迭代后变量增加的量。

python

range(start, stop, step)


for i in range(0, 10, 2):
print(i)

output
0
2
4
6
8

你甚至可以使用负数作为 step 参数,使 for 循环倒数而不是递增。

python
for i in range(5, -1, -1):
print(i)

output
5
4
3
2
1
0

For else 语句

这允许指定一个语句,在循环完全执行时执行。仅在循环中可能发生 break 条件时才有用:

python
for i in [1, 2, 3, 4, 5]:
if i == 3:
break
else:
print("only executed when no item is equal to 3")

使用 sys.exit() 结束程序

exit() 函数允许退出 Python。

python
import sys

while True:
feedback = input('Type exit to exit: ')
if feedback == 'exit':
print(f'You typed {feedback}.')
sys.exit()

output
Type exit to exit: open
Type exit to exit: close
Type exit to exit: exit
You typed exit.

相关链接

- <router-link to="/cheatsheet/basics">基础知识</router-link>
- <router-link to="/cheatsheet/functions">函数</router-link>
- <router-link to="/cheatsheet/exception-handling">异常处理</router-link>
- <router-link to="/cheatsheet/lists-and-tuples">列表和元组</router-link>
- <router-link to="/cheatsheet/sets">集合</router-link>
- <router-link to="/cheatsheet/dictionaries">字典</router-link>
- <router-link to="/cheatsheet/comprehensions">推导式</router-link>

---

Cheatsheet/Zh/Dataclasses

---
title: 'Python 数据类 - Python 速查表'
description: '数据类是 Python 类,但更适合存储数据对象。此模块提供了一个装饰器和函数,用于自动向用户定义的类添加生成的特殊方法,如 __init__() 和 __repr__()。'
labUrl: 'https://labex.io/zh/labs/python-python-dataclasses-633652?course=python-cheatsheet'
---

<base-title :title="frontmatter.title" :description="frontmatter.description">
Python 数据类
</base-title>

<base-lab-url :url="frontmatter.labUrl" />

Dataclasses 是 Python 类,但更适合存储数据对象。
此模块提供了一个装饰器和函数,用于自动向用户定义的类添加生成的特殊方法,例如 __init__()__repr__()

特性

1. 它们存储数据并代表某种数据类型。例如:一个数字。对于熟悉 ORM 的人来说,模型实例是一个数据对象。它代表特定类型的实体。它包含定义或表示该实体的属性。

2. 它们可以与相同类型的其他对象进行比较。例如:一个数字可以大于、小于或等于另一个数字。

Python 3.7 提供了一个装饰器 dataclass,用于将类转换为数据类。

python
class Number:
def __init__(self, val):
self.val = val

obj = Number(2)
obj.val

output
2

使用数据类

python

Dataclass: 自动生成 __init__ 和 __repr__ 方法


from dataclasses import dataclass

@dataclass # 装饰器将类转换为数据类
class Number:
val: int # 必须提供类型注解

obj = Number(2) # __init__ 自动创建
obj.val

output
2

默认值

可以轻松地为数据类的字段添加默认值。

python

带有默认值的数据类:带有默认值的字段必须放在没有默认值的字段之后


@dataclass
class Product:
name: str # 必需字段
count: int = 0 # 带有默认值的可选字段
price: float = 0.0 # 带有默认值的可选字段

obj = Product("Python") # 只需要 name,其他使用默认值
obj.name

output
Python

python
obj.count

output
0

python
obj.price

output
0.0

<BaseQuiz id="cheatsheet-dataclasses-1" correct="B">
<template #question>
在数据类中,带有默认值的字段必须放在哪里?
</template>

<BaseQuizOption value="A">A. 放在没有默认值的字段之前</BaseQuizOption>
<BaseQuizOption value="B" correct>B. 放在没有默认值的字段之后</BaseQuizOption>
<BaseQuizOption value="C">C. 哪里都行</BaseQuizOption>
<BaseQuizOption value="D">D. 在一个单独的部分</BaseQuizOption>
<BaseQuizAnswer>在数据类中,带有默认值的字段必须放在没有默认值的字段之后。这是因为 Python 需要知道生成的 <code>init</code> 方法中必需参数和可选参数的顺序。</BaseQuizAnswer>
</BaseQuiz>

类型提示

在数据类中定义数据类型是强制性的。但是,如果您不想指定数据类型,请使用 typing.Any

python
from dataclasses import dataclass
from typing import Any

@dataclass
class WithoutExplicitTypes:
name: Any
value: Any = 42

相关链接

- <router-link to="/cheatsheet/oop-basics">OOP 基础</router-link>
- <router-link to="/cheatsheet/decorators">装饰器</router-link>
- <router-link to="/blog/python-data-types">Python 数据类型博客文章</router-link>
- <router-link to="/builtin/object">object()</router-link>
- <router-link to="/builtin/repr">repr()</router-link>
- <router-link to="/builtin/type">type()</router-link>

---

Cheatsheet/Zh/Debugging

---
title: 'Python 调试 - Python 速查表'
description: '在计算机编程和软件开发中,调试是查找和解决计算机程序、软件或系统中错误(缺陷或阻止正确运行的问题)的过程。'
labUrl: 'https://labex.io/zh/labs/python-python-debugging-633653?course=python-cheatsheet'
---

<base-title :title="frontmatter.title" :description="frontmatter.description">
Python 调试
</base-title>

<base-lab-url :url="frontmatter.labUrl" />

<base-disclaimer>
<base-disclaimer-title>
<a target="_blank" href="https://en.wikipedia.org/wiki/Debugging">查找和解决 Bug</a>
</base-disclaimer-title>
<base-disclaimer-content>
在计算机编程和软件开发中,调试是查找和解决计算机程序、软件或系统中 Bug(缺陷或阻止正确运行的问题)的过程。
</base-disclaimer-content>
</base-disclaimer>

抛出异常 (Raising Exceptions)

使用 raise 语句抛出异常。在代码中,raise 语句包含以下内容:

- raise 关键字
- 对 Exception() 函数的调用
- 传递给 Exception() 函数的包含有用错误消息的字符串

python

raise 语句:使用自定义消息手动抛出异常


raise Exception('This is the error message.')

output
Traceback (most recent call last):
File "<pyshell#191>", line 1, in <module>
raise Exception('This is the error message.')
Exception: This is the error message.

<BaseQuiz id="cheatsheet-debugging-1" correct="B">
<template #question>
在 Python 中,用于手动抛出异常的关键字是什么?
</template>

<BaseQuizOption value="A">A. <code>throw</code></BaseQuizOption>
<BaseQuizOption value="B" correct>B. <code>raise</code></BaseQuizOption>
<BaseQuizOption value="C">C. <code>error</code></BaseQuizOption>
<BaseQuizOption value="D">D. <code>exception</code></BaseQuizOption>
<BaseQuizAnswer><code>raise</code> 关键字用于在 Python 中手动抛出异常。您可以抛出内置异常或自定义异常。</BaseQuizAnswer>
</BaseQuiz>

通常,知道如何处理异常的是调用函数的代码,而不是函数本身。因此,您通常会在函数内部看到 raise 语句,在调用函数的代码中看到 tryexcept 语句。

python

在函数中抛出异常,在调用代码中处理它们


def box_print(symbol, width, height):
if len(symbol) != 1:
raise Exception('Symbol must be a single character string.')
if width <= 2:
raise Exception('Width must be greater than 2.')
if height <= 2:
raise Exception('Height must be greater than 2.')
print(symbol * width)
for i in range(height - 2):
print(symbol + (' ' * (width - 2)) + symbol)
print(symbol * width)

处理调用函数时的异常


for sym, w, h in (('*', 4, 4), ('O', 20, 5), ('x', 1, 3), ('ZZ', 3, 3)):
try:
box_print(sym, w, h)
except Exception as err: # 捕获异常并打印错误消息
print('An exception happened: ' + str(err))

output




OOOOOOOOOOOOOOOOOOOO
O O
O O
O O
OOOOOOOOOOOOOOOOOOOO
An exception happened: Width must be greater than 2.
An exception happened: Symbol must be a single character string.

阅读更多关于 Exception Handling 的内容。

将回溯 (Traceback) 作为字符串获取

当抛出的异常未被处理时,Python 会显示 traceback。但也可以通过调用 traceback.format_exc() 将其作为字符串获取。如果您需要异常的 traceback 信息,但又希望 except 语句能够优雅地处理该异常,那么此函数非常有用。在调用此函数之前,您需要导入 Python 的 traceback 模块。

python

traceback.format_exc(): 获取回溯作为字符串用于日志记录/调试


import traceback

try:
raise Exception('This is the error message.')
except:
with open('errorInfo.txt', 'w') as error_file:
error_file.write(traceback.format_exc()) # 将回溯写入文件
print('The traceback info was written to errorInfo.txt.')

output
116
The traceback info was written to errorInfo.txt.

116 是 write() 方法的返回值,因为有 116 个字符被写入文件。traceback 文本已写入 errorInfo.txt。

Traceback (most recent call last):
File "<pyshell#28>", line 2, in <module>
Exception: This is the error message.

断言 (Assertions)

断言是一种完整性检查,用于确保您的代码没有做明显错误的事情。这些完整性检查由 assert 语句执行。如果完整性检查失败,则会引发 AssertionError 异常。在代码中,assert 语句包含以下内容:

- assert 关键字
- 一个条件(即一个求值为 TrueFalse 的表达式)
- 一个逗号
- 当条件为 False 时显示的 string

python

assert 语句:检查条件,如果为 False 则抛出 AssertionError


pod_bay_door_status = 'open'
assert pod_bay_door_status == 'open', 'The pod bay doors need to be "open".' # 通过

pod_bay_door_status = 'I\'m sorry, Dave. I\'m afraid I can\'t do that.'
assert pod_bay_door_status == 'open', 'The pod bay doors need to be "open".' # 抛出 AssertionError

output
Traceback (most recent call last):
File "<pyshell#10>", line 1, in <module>
assert pod_bay_door_status == 'open', 'The pod bay doors need to be "open".'
AssertionError: The pod bay doors need to be "open".

<BaseQuiz id="cheatsheet-debugging-2" correct="C">
<template #question>
当 <code>assert</code> 语句失败时会发生什么?
</template>

<BaseQuizOption value="A">A. 程序继续运行</BaseQuizOption>
<BaseQuizOption value="B">B. 打印警告</BaseQuizOption>
<BaseQuizOption value="C" correct>C. 抛出 <code>AssertionError</code> 并且程序应该崩溃</BaseQuizOption>
<BaseQuizOption value="D">D. 条件自动修复</BaseQuizOption>
<BaseQuizAnswer>当 <code>assert</code> 语句失败时,它会抛出 <code>AssertionError</code>。与异常不同,不应使用 try-except 来捕获 assert 语句;如果 assert 失败,您的程序应该崩溃,以帮助您快速找到 Bug。</BaseQuizAnswer>
</BaseQuiz>

用通俗的话来说,assert 语句的意思是:“我断言这个条件为真,如果不是,那么程序中就存在一个 Bug。”与异常不同,您的代码不应该使用 try 和 except 来处理 assert 语句;如果 assert 失败,您的程序应该崩溃。通过这种快速失败的方式,您可以缩短从 Bug 的原始原因到您首次注意到该 Bug 之间的时间,这将减少您需要检查以查找导致 Bug 的代码的量。

禁用断言

通过在运行 Python 时传递 -O 选项可以禁用断言。

日志记录 (Logging)

要使 logging 模块能够在程序运行时在屏幕上显示日志消息,请将以下内容复制到程序的顶部:

python
import logging
logging.basicConfig(level=logging.DEBUG, format=' %(asctime)s - %(levelname)s- %(message)s')

<BaseQuiz id="cheatsheet-debugging-3" correct="A">
<template #question>
Python 中 <code>logging</code> 模块的目的是什么?
</template>

<BaseQuizOption value="A" correct>A. 记录程序执行信息以供调试和监控</BaseQuizOption>
<BaseQuizOption value="B">B. 防止错误发生</BaseQuizOption>
<BaseQuizOption value="C">C. 加快程序执行速度</BaseQuizOption>
<BaseQuizOption value="D">D. 加密日志消息</BaseQuizOption>
<BaseQuizAnswer><code>logging</code> 模块允许您记录程序执行信息(在不同级别:DEBUG、INFO、WARNING、ERROR、CRITICAL),这对于调试和监控非常有用。</BaseQuizAnswer>
</BaseQuiz>

假设您编写了一个函数来计算一个数的阶乘。在数学中,4 的阶乘是 1 × 2 × 3 × 4,即 24。7 的阶乘是 1 × 2 × 3 × 4 × 5 × 6 × 7,即 5,040。打开一个新的文件编辑器窗口,输入以下代码。它有一个 Bug,但您也将输入几条日志消息来帮助自己找出哪里出了问题。将程序保存为 factorialLog.py。

python
import logging
logging.basicConfig(level=logging.DEBUG, format=' %(asctime)s - %(levelname)s- %(message)s')
logging.debug('Start of program')

def factorial(n):
logging.debug('Start of factorial(%s)' % (n))
total = 1
for i in range(0, n + 1):
total *= i
logging.debug('i is ' + str(i) + ', total is ' + str(total))
logging.debug('End of factorial(%s)' % (n))
return total

print(factorial(5))
logging.debug('End of program')

output
2015-05-23 16:20:12,664 - DEBUG - Start of program
2015-05-23 16:20:12,664 - DEBUG - Start of factorial(5)
2015-05-23 16:20:12,665 - DEBUG - i is 0, total is 0
2015-05-23 16:20:12,668 - DEBUG - i is 1, total is 0
2015-05-23 16:20:12,670 - DEBUG - i is 2, total is 0
2015-05-23 16:20:12,673 - DEBUG - i is 3, total is 0
2015-05-23 16:20:12,675 - DEBUG - i is 4, total is 0
2015-05-23 16:20:12,678 - DEBUG - i is 5, total is 0
2015-05-23 16:20:12,680 - DEBUG - End of factorial(5)
0
2015-05-23 16:20:12,684 - DEBUG - End of program

日志级别 (Logging Levels)

日志级别提供了一种按重要性对日志消息进行分类的方法。有五个日志级别,如表 10-1 所示,按重要性从低到高描述。可以使用不同的日志记录函数在每个级别记录消息。

| 级别 | 日志记录函数 | 描述 |
| ---------- | -------------------- | -------------------------------------------------------------- |
| DEBUG | logging.debug() | 最低级别。用于记录小细节。通常只有在诊断问题时才关心这些消息。 |
| INFO | logging.info() | 用于记录程序中一般事件的信息,或确认程序在特定点按预期工作。 |
| WARNING | logging.warning() | 用于指示潜在问题,该问题不会阻止程序运行,但将来可能会。 |
| ERROR | logging.error() | 用于记录导致程序未能执行某项操作的错误。 |
| CRITICAL | logging.critical() | 最高级别。用于指示已导致或即将导致程序完全停止运行的致命错误。 |

<BaseQuiz id="cheatsheet-debugging-4" correct="D">
<template #question>
Python 中最低的日志级别是什么?
</template>

<BaseQuizOption value="A">A. <code>INFO</code></BaseQuizOption>
<BaseQuizOption value="B">B. <code>WARNING</code></BaseQuizOption>
<BaseQuizOption value="C">C. <code>ERROR</code></BaseQuizOption>
<BaseQuizOption value="D" correct>D. <code>DEBUG</code></BaseQuizOption>
<BaseQuizAnswer>日志级别从低到高依次是:<code>DEBUG</code>、<code>INFO</code>、<code>WARNING</code>、<code>ERROR</code>、<code>CRITICAL</code>。<code>DEBUG</code> 是最低级别,用于详细的诊断信息。</BaseQuizAnswer>
</BaseQuiz>

禁用日志记录

在调试完程序后,您可能不希望所有这些日志消息都充斥在屏幕上。logging.disable() 函数可以禁用它们,这样您就不必手动进入程序中删除所有日志调用。

python
import logging

logging.basicConfig(level=logging.INFO, format=' %(asctime)s -%(levelname)s - %(message)s')
logging.critical('Critical error! Critical error!')

output
2015-05-22 11:10:48,054 - CRITICAL - Critical error! Critical error!

python
logging.disable(logging.CRITICAL)
logging.critical('Critical error! Critical error!')
logging.error('Error! Error!')

日志记录到文件 (Logging to a File)

您可以将日志消息写入文本文件,而不是将它们显示在屏幕上。logging.basicConfig() 函数接受一个 filename 关键字参数,如下所示:

python
import logging
logging.basicConfig(filename='myProgramLog.txt', level=logging.DEBUG, format='%(asctime)s - %(levelname)s - %(message)s')

<BaseQuiz id="cheatsheet-debugging-5" correct="B">
<template #question>
如何将日志消息写入文件而不是显示在屏幕上?
</template>

<BaseQuizOption value="A">A. 使用 <code>logging.file()</code></BaseQuizOption>
<BaseQuizOption value="B" correct>B. 将 <code>filename</code> 参数传递给 <code>logging.basicConfig()</code></BaseQuizOption>
<BaseQuizOption value="C">C. 使用 <code>logging.write()</code></BaseQuizOption>
<BaseQuizOption value="D">D. 日志总是自动写入文件</BaseQuizOption>
<BaseQuizAnswer>要将日志消息写入文件,请将 <code>filename</code> 参数传递给 <code>logging.basicConfig()</code>。这将把所有日志消息写入指定的日志文件,而不是显示在屏幕上。</BaseQuizAnswer>
</BaseQuiz>

相关链接

- <router-link to="/cheatsheet/exception-handling">异常处理</router-link>
- <router-link to="/builtin/breakpoint">breakpoint()</router-link>

---

Cheatsheet/Zh/Decorators

---
title: 'Python 装饰器 - Python 速查表'
description: 'Python 装饰器是一种语法,为扩展函数或类提供了一种简洁且可重用的方式。'
labUrl: 'https://labex.io/zh/labs/python-python-decorators-633654?course=python-cheatsheet'
---

<base-title :title="frontmatter.title" :description="frontmatter.description">
Python 装饰器
</base-title>

<base-lab-url :url="frontmatter.labUrl" />

Python 装饰器提供了一种简洁且可重用的方式来扩展函数或类。阅读配套文章 <router-link to="/blog/python-decorators-for-beginners">Python 装饰器:提升代码水平的简单模式</router-link> 以获取实用的示例和模式。

基础装饰器

最简单的装饰器形式是一个接受另一个函数作为参数并返回一个包装器的函数。以下示例展示了装饰器的创建及其用法。

python

装饰器:一个接受另一个函数并返回一个包装器的函数


def your_decorator(func):
def wrapper():
# 在 func 之前执行操作...
print("Before func!")
func() # 调用原始函数
# 在 func 之后执行操作...
print("After func!")
return wrapper # 返回包装器函数

@your_decorator 是以下语法的简写:foo = your_decorator(foo)


@your_decorator
def foo():
print("Hello World!")

foo() # 调用 wrapper,它会调用 foo 并添加额外行为

output
Before func!
Hello World!
After func!

<BaseQuiz id="cheatsheet-decorators-1" correct="A">
<template #question>
Python 中的装饰器是什么?
</template>

<BaseQuizOption value="A" correct>A. 一个接受另一个函数并返回一个包装器函数的函数</BaseQuizOption>
<BaseQuizOption value="B">B. 一种特殊的类</BaseQuizOption>
<BaseQuizOption value="C">C. 一个内置的 Python 关键字</BaseQuizOption>
<BaseQuizOption value="D">D. 一种删除函数的方法</BaseQuizOption>
<BaseQuizAnswer>装饰器是一个接受另一个函数作为参数并返回一个包装器函数的函数。<code>@</code> 语法是应用于函数的装饰器的简写。</BaseQuizAnswer>
</BaseQuiz>

带有参数的函数装饰器

python

适用于带有参数的函数的装饰器


def your_decorator(func):
def wrapper(args,*kwargs): # 接受任何参数
# 在 func 之前执行操作...
print("Before func!")
func(args,*kwargs) # 将参数传递给原始函数
# 在 func 之后执行操作...
print("After func!")
return wrapper

@your_decorator
def foo(bar):
print("My name is " + bar)

foo("Jack") # 参数通过 wrapper 传递

output
Before func!
My name is Jack
After func!

基础装饰器模板

此模板适用于大多数装饰器用例。它适用于带参数或不带参数,以及有返回值或无返回值的函数。

python
import functools

最佳实践装饰器模板:保留函数元数据和返回值


def your_decorator(func):
@functools.wraps(func) # 保留函数名、文档字符串等
def wrapper(args,*kwargs):
# 在 func 之前执行操作...
result = func(args,*kwargs) # 调用函数并捕获返回值
# 在 func 之后执行操作..
return result # 返回原始函数的返回值
return wrapper

<BaseQuiz id="cheatsheet-decorators-2" correct="B">
<template #question>
<code>@functools.wraps(func)</code> 在装饰器中做什么?
</template>

<BaseQuizOption value="A">A. 使装饰器执行得更快</BaseQuizOption>
<BaseQuizOption value="B" correct>B. 保留原始函数的元数据(名称、文档字符串等)</BaseQuizOption>
<BaseQuizOption value="C">C. 阻止函数被调用</BaseQuizOption>
<BaseQuizOption value="D">D. 将函数转换为类</BaseQuizOption>
<BaseQuizAnswer><code>@functools.wraps(func)</code> 装饰器将原始函数的元数据(如其名称和文档字符串)保留在包装器函数中。在编写装饰器时,这被认为是一种最佳实践。</BaseQuizAnswer>
</BaseQuiz>

带参数的装饰器

您也可以为装饰器定义参数。

python
import functools

装饰器工厂:根据参数返回一个装饰器


def your_decorator(arg):
def decorator(func):
@functools.wraps(func) # 保留函数元数据
def wrapper(args,*kwargs):
# 在 func 之前执行操作,可能使用 arg...
result = func(args,*kwargs)
# 在 func 之后执行操作,可能使用 arg...
return result
return wrapper
return decorator # 返回实际的装饰器函数

要使用此装饰器:

python

使用带参数的装饰器:@your_decorator(arg='x') 调用 your_decorator('x')


然后返回一个装饰器,该装饰器应用于 foo


@your_decorator(arg = 'x')
def foo(bar):
return bar

基于类的装饰器

要装饰类方法,必须在类内部定义装饰器。当只将隐式参数 self 传递给方法,而没有其他显式参数时,必须为仅具有这些参数的方法创建单独的装饰器。下面的示例展示了这种情况,例如当您想以某种方式捕获和打印异常时。

python

类方法装饰器:在类内部定义


class DecorateMyMethod:

# 仅包含 'self' 参数的类方法的静态方法装饰器
def decorator_for_class_method_with_no_args(method):
def wrapper_for_class_method(self): # 只接收 self
try:
return method(self) # 调用原始方法
except Exception as e:
print("\nWARNING: Please make note of the following:\n")
print(e)
return wrapper_for_class_method

def __init__(self,succeed:bool):
self.succeed = succeed

@decorator_for_class_method_with_no_args
def class_action(self):
if self.succeed:
print("You succeeded by choice.")
else:
raise Exception("Epic fail of your own creation.")

test_succeed = DecorateMyMethod(True)
test_succeed.class_action()

output
You succeeded by choice.

python
test_fail = DecorateMyMethod(False)
test_fail.class_action()

output
Exception: Epic fail of your own creation.

装饰器也可以定义为一个类而不是一个方法。这对于维护和更新状态很有用,如以下示例所示,我们计算对某个方法的调用次数:

python

基于类的装饰器:在调用之间维护状态


class CountCallNumber:

def __init__(self, func):
self.func = func # 存储要装饰的函数
self.call_number = 0 # 初始化调用计数器

def __call__(self, args, *kwargs): # 使实例可调用
self.call_number += 1 # 增加计数器
print("This is execution number " + str(self.call_number))
return self.func(args, *kwargs) # 调用原始函数

@CountCallNumber # 创建 CountCallNumber 的实例
def say_hi(name):
print("Hi! My name is " + name)

say_hi("Jack") # 调用 CountCallNumber.__call__()

output
This is execution number 1
Hi! My name is Jack

python
say_hi("James")

output
This is execution number 2
Hi! My name is James

<base-disclaimer>
<base-disclaimer-title>
计数示例
</base-disclaimer-title>
<base-disclaimer-content>
此计数示例的灵感来源于 Patrick Loeber 的 <a href="https://youtu.be/HGOBQPFzWKo?si=IUvFzeQbzTmeEgKV" target="_blank">YouTube 教程</a>。
</base-disclaimer-content>
</base-disclaimer>

相关链接

- <router-link to="/blog/python-decorators-for-beginners">Python 装饰器:提升代码水平的简单模式</router-link>
- <router-link to="/blog/python-easy-args-kwargs">Python \args 和 \\*kwargs 轻松掌握</router-link>
- <router-link to="/cheatsheet/functions">函数</router-link>
- <router-link to="/cheatsheet/args-and-kwargs">Args 和 Kwargs</router-link>
- <router-link to="/builtin/classmethod">classmethod()</router-link>
- <router-link to="/builtin/staticmethod">staticmethod()</router-link>
- <router-link to="/builtin/property">property()</router-link>
- <router-link to="/builtin/callable">callable()</router-link>

---

Cheatsheet/Zh/Dictionaries

---
title: 'Python 字典 - Python 速查表'
description: '在 Python 中,字典是键值对的有序集合(Python > 3.7 版本中保持插入顺序)。'
labUrl: 'https://labex.io/zh/labs/python-python-dictionaries-633655?course=python-cheatsheet'
---

<base-title :title="frontmatter.title" :description="frontmatter.description">
Python 字典
</base-title>

<base-lab-url :url="frontmatter.labUrl" />

在 Python 中,字典是 key: value 对的有序(Python > 3.7 起)集合。

<base-disclaimer>
<base-disclaimer-title>
来自 Python 3 <a target="_blank" href="https://docs.python.org/3/tutorial/datastructures.html#dictionaries">文档</a>
</base-disclaimer-title>
<base-disclaimer-content>
字典的主要操作是使用某个键存储一个值,以及给定一个键来提取该值。也可以使用 <code>del</code> 删除一个键:值对。
</base-disclaimer-content>
</base-disclaimer>

示例字典:

python

字典:键值对的集合


my_cat = {
'size': 'fat', # 键:'size', 值:'fat'
'color': 'gray', # 键:'color', 值:'gray'
'disposition': 'loud' # 键:'disposition', 值:'loud'
}

使用下标运算符 [] 设置键、值

python

使用下标运算符添加或更新字典条目


my_cat = {
'size': 'fat',
'color': 'gray',
'disposition': 'loud',
}
my_cat['age_years'] = 2 # 添加新的键值对
print(my_cat)

output
{'size': 'fat', 'color': 'gray', 'disposition': 'loud', 'age_years': 2}

使用下标运算符 [] 获取值

如果字典中不存在该键,则会引发 <a target="_blank" href="https://docs.python.org/3/library/exceptions.html#KeyError">KeyError</a>。

python
my_cat = {
'size': 'fat',
'color': 'gray',
'disposition': 'loud',
}
print(my_cat['size'])

output
fat

python
print(my_cat['eye_color'])

output
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
KeyError: 'eye_color'

values()

values() 方法获取字典的

python

使用 .values() 方法迭代字典值


pet = {'color': 'red', 'age': 42}
for value in pet.values(): # 遍历所有值
print(value)

output
red
42

keys()

keys() 方法获取字典的

python

使用 .keys() 方法迭代字典键


pet = {'color': 'red', 'age': 42}
for key in pet.keys(): # 遍历所有键
print(key)

output
color
age

由于默认情况下您将遍历键,因此没有必要使用 .keys()

python

直接迭代字典会遍历键(默认行为)


pet = {'color': 'red', 'age': 42}
for key in pet: # 等同于 for key in pet.keys()
print(key)

output
color
age

items()

items() 方法获取字典的,并将它们作为 <router-link to=/cheatsheet/lists-and-tuples#the-tuple-data-type>元组 (Tuple)</router-link> 返回:

python
pet = {'color': 'red', 'age': 42}
for item in pet.items():
print(item)

output
('color', 'red')
('age', 42)

使用 keys()values()items() 方法,for 循环可以分别迭代字典中的键、值或键值对。

python

使用 .items() 方法迭代键值对


pet = {'color': 'red', 'age': 42}
for key, value in pet.items(): # 将元组解包为键和值
print(f'Key: {key} Value: {value}')

output
Key: color Value: red
Key: age Value: 42

get()

get() 方法返回具有给定键的项的值。如果键不存在,它返回 None

python

.get() 方法:安全地检索值,如果键不存在则返回 None


wife = {'name': 'Rose', 'age': 33}

f'My wife name is {wife.get("name")}' # 返回 'Rose'

output
'My wife name is Rose'

python
f'She is {wife.get("age")} years old.'

output
'She is 33 years old.'

python
f'She is deeply in love with {wife.get("husband")}'

output
'She is deeply in love with None'

您也可以将默认的 None 值更改为您选择的任何值:

python
wife = {'name': 'Rose', 'age': 33}

f'She is deeply in love with {wife.get("husband", "lover")}'

output
'She is deeply in love with lover'

使用 setdefault() 添加项

可以通过这种方式向字典添加一个项:

python
wife = {'name': 'Rose', 'age': 33}
if 'has_hair' not in wife:
wife['has_hair'] = True

使用 setdefault 方法,我们可以使相同的代码更简洁:

python
wife = {'name': 'Rose', 'age': 33}
wife.setdefault('has_hair', True)
wife

output
{'name': 'Rose', 'age': 33, 'has_hair': True}

移除项

pop()

pop() 方法根据给定的键移除并返回一个项。

python
wife = {'name': 'Rose', 'age': 33, 'hair': 'brown'}
wife.pop('age')

output
33

python
wife

output
{'name': 'Rose', 'hair': 'brown'}

<BaseQuiz id="cheatsheet-dictionaries-1" correct="B">
<template #question>
当在字典上调用 <code>pop()</code> 时,它会做什么?
</template>

<BaseQuizOption value="A">A. 只移除键值对</BaseQuizOption>
<BaseQuizOption value="B" correct>B. 移除并返回指定键的值</BaseQuizOption>
<BaseQuizOption value="C">C. 只返回值而不移除它</BaseQuizOption>
<BaseQuizOption value="D">D. 移除字典中的所有项</BaseQuizOption>
<BaseQuizAnswer><code>pop()</code> 方法会移除指定键的键值对并返回该值。如果键不存在,它会引发 <code>KeyError</code>(除非您提供一个默认值)。</BaseQuizAnswer>
</BaseQuiz>

popitem()

popitem() 方法移除字典中的最后一个项并返回它。

python
wife = {'name': 'Rose', 'age': 33, 'hair': 'brown'}
wife.popitem()

output
('hair', 'brown')

python
wife

output
{'name': 'Rose', 'age': 33}

del

del 方法根据给定的键移除一个项。

python
wife = {'name': 'Rose', 'age': 33, 'hair': 'brown'}
del wife['age']
wife

output
{'name': 'Rose', 'hair': 'brown'}

clear()

clear() 方法移除字典中的所有项。

python
wife = {'name': 'Rose', 'age': 33, 'hair': 'brown'}
wife.clear()
wife

output
{}

在字典中检查键

python
person = {'name': 'Rose', 'age': 33}

'name' in person.keys()

output
True

python
'height' in person.keys()

output
False

python
'skin' in person # 可以省略 keys()

output
False

在字典中检查值

python
person = {'name': 'Rose', 'age': 33}

'Rose' in person.values()

output
True

python
33 in person.values()

output
True

漂亮打印 (Pretty Printing)

python
import pprint

wife = {'name': 'Rose', 'age': 33, 'has_hair': True, 'hair_color': 'brown', 'height': 1.6, 'eye_color': 'brown'}
pprint.pprint(wife)

output
{'age': 33,
'eye_color': 'brown',
'hair_color': 'brown',
'has_hair': True,
'height': 1.6,
'name': 'Rose'}

合并两个字典

对于 Python 3.5+:

注意:解包语法适用于 Python 3.5+,而字典显示顺序从 Python 3.7+ 起才得到保证。

python
dict_a = {'a': 1, 'b': 2}
dict_b = {'b': 3, 'c': 4}
dict_c = {dict_b, dict_a}
dict_c

output
{'b': 2, 'c': 4, 'a': 1}

<BaseQuiz id="cheatsheet-dictionaries-2" correct="B">
<template #question>
当使用 <code>{dict_b, dict_a}</code> 合并两个字典时,如果两个字典具有相同的键,会发生什么?
</template>

<BaseQuizOption value="A">A. <code>dict_b</code> 中的值会覆盖 <code>dict_a</code> 中的值</BaseQuizOption>
<BaseQuizOption value="B" correct>B. <code>dict_a</code> 中的值会覆盖 <code>dict_b</code> 中的值</BaseQuizOption>
<BaseQuizOption value="C">C. 两个值都会被保留在一个列表中</BaseQuizOption>
<BaseQuizOption value="D">D. 引发错误</BaseQuizOption>
<BaseQuizAnswer>当使用 <code>\\</code> 解包运算符合并字典时,如果两个字典具有相同的键,后出现的字典(在本例中为 <code>dict_a</code>)中的值会覆盖先出现的字典中的值。</BaseQuizAnswer>
</BaseQuiz>

相关链接

- <router-link to="/blog/python-data-types">Python 数据类型博客文章</router-link>
- <router-link to="/blog/python-easy-args-kwargs">Python \args 和 \\*kwargs 变得简单</router-link>
- <router-link to="/cheatsheet/comprehensions">推导式 (Comprehensions)</router-link>
- <router-link to="/cheatsheet/args-and-kwargs">Args 和 Kwargs</router-link>
- <router-link to="/blog/python-comprehensions-step-by-step">Python 推导式分步指南</router-link>
- <router-link to="/builtin/dict">dict()</router-link>
- <router-link to="/builtin/len">len()</router-link>
- <router-link to="/builtin/iter">iter()</router-link>
- <router-link to="/builtin/zip">zip()</router-link>

---

Cheatsheet/Zh/Exception Handling

---
title: 'Python 异常处理 - Python 速查表'
description: '在 Python 中,异常处理是响应程序中发生异常的过程。'
labUrl: 'https://labex.io/zh/labs/python-python-exception-handling-633656?course=python-cheatsheet'
---

<base-title :title="frontmatter.title" :description="frontmatter.description">
Python 异常处理
</base-title>

<base-lab-url :url="frontmatter.labUrl" />

<base-disclaimer>
<base-disclaimer-title>
<a target="_blank" href="https://en.wikipedia.org/wiki/Exception_handling">异常处理</a>
</base-disclaimer-title>
<base-disclaimer-content>
在计算和计算机编程中,异常处理是响应异常——需要特殊处理的反常或例外情况——的过程。
</base-disclaimer-content>
</base-disclaimer>

Python 有许多内置异常,当程序遇到错误时会引发这些异常,并且大多数外部库,如流行的 Requests,都包含其自定义异常,我们需要进行处理。

基本异常处理

你不能除以零,这是一个数学真理,如果你在 Python 中尝试这样做,解释器将引发内置异常 ZeroDivisionError

python
def divide(dividend , divisor):
print(dividend / divisor)

divide(dividend=10, divisor=5)

output
2

python
divide(dividend=10, divisor=0)

output
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
ZeroDivisionError: division by zero

假设我们不希望程序停止执行或向用户显示他们无法理解的输出。假设我们想打印一条有用且清晰的消息,那么我们需要使用 tryexcept 关键字来_处理_异常:

python

try-except: 优雅地处理异常


def divide(dividend , divisor):
try: # 尝试执行此代码
print(dividend / divisor)
except ZeroDivisionError: # 捕获特定异常类型
print('你不能除以 0')

divide(dividend=10, divisor=5)

output
2

python
divide(dividend=10, divisor=0)

output
你不能除以 0

<BaseQuiz id="cheatsheet-exception-handling-1" correct="A">
<template #question>
在 Python 中,使用哪些关键字来处理异常?
</template>

<BaseQuizOption value="A" correct>A. <code>try</code> 和 <code>except</code></BaseQuizOption>
<BaseQuizOption value="B">B. <code>catch</code> 和 <code>handle</code></BaseQuizOption>
<BaseQuizOption value="C">C. <code>error</code> 和 <code>rescue</code></BaseQuizOption>
<BaseQuizOption value="D">D. <code>if</code> 和 <code>else</code></BaseQuizOption>
<BaseQuizAnswer>Python 使用 <code>try</code> 来标记可能引发异常的代码,使用 <code>except</code> 来处理发生的特定异常。</BaseQuizAnswer>
</BaseQuiz>

使用一个异常块处理多个异常

你也可以像下面这样在一行中处理多个异常,而无需创建多个异常块。

python

在一个 except 块中处理多个异常


def divide(dividend , divisor):
try:
if (dividend == 10):
var = 'str' + 1 # 这将引发 TypeError
else:
print(dividend / divisor)
except (ZeroDivisionError, TypeError) as error: # 捕获多种异常类型
print(error) # 打印错误消息

divide(dividend=20, divisor=5)

output
4

python
divide(dividend=10, divisor=5)

output
can only concatenate str (not "int") to str

python
divide(dividend=10, divisor=0)

output
division by zero

<BaseQuiz id="cheatsheet-exception-handling-2" correct="B">
<template #question>
可以在单个 <code>except</code> 块中处理多种异常类型吗?
</template>

<BaseQuizOption value="A">A. 不行,必须为每种异常类型使用单独的 <code>except</code> 块</BaseQuizOption>
<BaseQuizOption value="B" correct>B. 可以,通过将它们放在一个元组中,如 <code>except (Exception1, Exception2)</code></BaseQuizOption>
<BaseQuizOption value="C">C. 可以,但仅当它们相关时</BaseQuizOption>
<BaseQuizOption value="D">D. 不行,Python 不支持此功能</BaseQuizOption>
<BaseQuizAnswer>你可以通过将多种异常类型放在一个元组中来在一个 <code>except</code> 块中处理它们:<code>except (ZeroDivisionError, TypeError) as error:</code></BaseQuizAnswer>
</BaseQuiz>

异常处理中的 Finally 代码

无论是否引发异常,finally 部分中的代码始终会被执行:

python

finally 块:无论是否发生异常,都会执行


def divide(dividend , divisor):
try:
print(dividend / divisor)
except ZeroDivisionError:
print('你不能除以 0')
finally: # 无论是否发生异常,都始终执行
print('执行完毕')

divide(dividend=10, divisor=5)

output
2.0
执行完毕

python
divide(dividend=10, divisor=0)

output
你不能除以 0
执行完毕

<BaseQuiz id="cheatsheet-exception-handling-3" correct="C">
<template #question>
<code>finally</code> 块何时执行?
</template>

<BaseQuizOption value="A">A. 仅在发生异常时</BaseQuizOption>
<BaseQuizOption value="B">B. 仅在未发生异常时</BaseQuizOption>
<BaseQuizOption value="C" correct>C. 始终执行,无论是否发生异常</BaseQuizOption>
<BaseQuizOption value="D">D. 从不执行</BaseQuizOption>
<BaseQuizAnswer><code>finally</code> 块始终执行,无论是否发生异常。它对于无论结果如何都必须运行的清理代码很有用。</BaseQuizAnswer>
</BaseQuiz>

自定义异常

自定义异常通过创建继承自 Python 的基类 Exceptionclass 来初始化,并使用 raise 关键字引发:

python

自定义异常:通过继承 Exception 类创建


class MyCustomException(Exception):
pass

raise MyCustomException # 引发自定义异常

output
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
__main__.MyCustomException

要声明自定义异常消息,可以将其作为参数传递:

python
class MyCustomException(Exception):
pass

raise MyCustomException('A custom message for my custom exception')

output
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
__main__.MyCustomException: A custom message for my custom exception

处理自定义异常与处理任何其他异常相同:

python
try:
raise MyCustomException('A custom message for my custom exception')
except MyCustomException:
print('My custom exception was raised')

output
My custom exception was raised

<BaseQuiz id="cheatsheet-exception-handling-4" correct="A">
<template #question>
如何在 Python 中创建自定义异常?
</template>

<BaseQuizOption value="A" correct>A. 创建一个继承自 <code>Exception</code> 类的类</BaseQuizOption>
<BaseQuizOption value="B">B. 使用 <code>@exception</code> 装饰器</BaseQuizOption>
<BaseQuizOption value="C">C. 调用 <code>Exception.create()</code></BaseQuizOption>
<BaseQuizOption value="D">D. 从特殊模块导入它</BaseQuizOption>
<BaseQuizAnswer>自定义异常是通过定义一个继承自基类 <code>Exception</code> 的类来创建的。然后你可以像处理内置异常一样引发和处理它们。</BaseQuizAnswer>
</BaseQuiz>

相关链接

- <router-link to="/cheatsheet/control-flow">控制流</router-link>
- <router-link to="/builtin/breakpoint">breakpoint()</router-link>
- <router-link to="/builtin/isinstance">isinstance()</router-link>
- <router-link to="/builtin/issubclass">issubclass()</router-link>

---

Cheatsheet/Zh/File Directory Path

---
title: '文件和目录路径 - Python 速查表'
description: 'Python 中有两个主要模块处理路径操作:os.path 模块和 pathlib 模块。'
labUrl: 'https://labex.io/zh/labs/python-python-file-and-directory-path-manipulation-633657?course=python-cheatsheet'
---

<base-title :title="frontmatter.title" :description="frontmatter.description">
处理文件和目录路径
</base-title>

<base-lab-url :url="frontmatter.labUrl" />

有关实用文件系统操作的深入探讨,请参阅我们的博客文章:<router-link to="/blog/python-pathlib-essentials">每位开发者都应知道的 10 个基本文件系统操作</router-link>。

Python 中有两个主要模块处理路径操作。
一个是 <router-link to="/modules/os-module">os.path</router-link> 模块,另一个是 <router-link to="/modules/pathlib-module">pathlib</router-link> 模块。

<base-disclaimer>
<base-disclaimer-title>
Pathlib 与 OS 模块
</base-disclaimer-title>
<base-disclaimer-content>
<code>pathlib</code> 提供了比上面列出的更多的功能,例如获取文件名、获取文件扩展名、在不手动打开的情况下读取/写入文件等。如果您打算了解更多信息,请参阅<a target="_blank" href="https://docs.python.org/3/library/pathlib.html">官方文档</a>。
</base-disclaimer-content>
</base-disclaimer>

Linux 和 Windows 路径

在 Windows 上,路径使用反斜杠 (\) 作为文件夹名称之间的分隔符。在基于 Unix 的操作系统(如 macOS、Linux 和 BSD)上,使用正斜杠 (/) 作为路径分隔符。如果您的代码需要在不同平台上运行,连接路径可能会很麻烦。

幸运的是,Python 的 pathlib 模块提供了一种简单的方法来处理这个问题。

在 \*nix 上使用 pathlib

python

pathlib.Path: 跨平台路径处理


from pathlib import Path

print(Path('usr').joinpath('bin').joinpath('spam')) # 连接路径组件

output
usr/bin/spam

pathlib 还通过 / 运算符提供了 joinpath 的快捷方式:

python

Path 运算符 (/): 连接路径的便捷方式(跨平台)


from pathlib import Path

print(Path('usr') / 'bin' / 'spam') # 使用 / 运算符代替 joinpath()

output
usr/bin/spam

请注意,路径分隔符在 Windows 和基于 Unix 的操作系统之间是不同的,这就是您想要使用 pathlib 而不是将字符串连接起来以连接路径的原因。

<BaseQuiz id="cheatsheet-file-directory-path-1" correct="B">
<template #question>
在 Python 中,使用 pathlib 连接路径的正确方法是什么?
</template>

<BaseQuizOption value="A">A. <code>Path('usr') + 'bin' + 'spam'</code></BaseQuizOption>
<BaseQuizOption value="B" correct>B. <code>Path('usr') / 'bin' / 'spam'</code></BaseQuizOption>
<BaseQuizOption value="C">C. <code>Path('usr').join('bin').join('spam')</code></BaseQuizOption>
<BaseQuizOption value="D">D. <code>Path('usr/bin/spam')</code></BaseQuizOption>
<BaseQuizAnswer><code>/</code> 运算符是使用 pathlib 连接路径的推荐方法。它具有跨平台性,并且比字符串连接更具可读性。</BaseQuizAnswer>
</BaseQuiz>

连接路径在您需要在同一目录下创建不同文件路径时非常有用。

在 \*nix 上使用 pathlib

python

Path.home(): 获取用户的主目录,与文件名组合


my_files = ['accounts.txt', 'details.csv', 'invite.docx']
home = Path.home() # 获取主目录路径
for filename in my_files:
print(home / filename) # 将主路径与每个文件名组合

output
/home/labex/project/accounts.txt
/home/labex/project/details.csv
/home/labex/project/invite.docx

展开用户主目录

使用 os.path.expanduser()~ 展开为用户的主目录:

python
import os.path

将 ~ 展开为用户的主目录


print(os.path.expanduser('~'))

output
/home/labex/project

python

展开 ~/Documents 为完整路径


print(os.path.expanduser('~/Documents'))

output
/home/labex/project/Documents

python

适用于包含 ~ 的路径


print(os.path.expanduser('~/myfile.txt'))

output
/home/labex/project/myfile.txt

当前工作目录

您可以使用 pathlib 获取当前工作目录:

python

Path.cwd(): 获取当前工作目录


from pathlib import Path

print(Path.cwd()) # 以 Path 对象形式返回当前工作目录

output
/home/labex/project

创建新文件夹

在 \*nix 上使用 pathlib

python
from pathlib import Path
cwd = Path.cwd()
(cwd / 'delicious' / 'walnut' / 'waffles').mkdir()

output
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/usr/lib/python3.6/pathlib.py", line 1226, in mkdir
self._accessor.mkdir(self, mode)
File "/usr/lib/python3.6/pathlib.py", line 387, in wrapped
return strfunc(str(pathobj), *args)
FileNotFoundError: [Errno 2] No such file or directory: '/home/labex/project/delicious/walnut/waffles'

哦,糟了,我们遇到了一个棘手的错误!原因是 'delicious' 目录不存在,所以我们无法在它下面创建 'walnut' 和 'waffles' 目录。要修复此问题,请执行以下操作:

python

mkdir(parents=True): 如果需要,创建目录和所有父目录


from pathlib import Path
cwd = Path.cwd()
(cwd / 'delicious' / 'walnut' / 'waffles').mkdir(parents=True) # 创建嵌套目录

一切就绪 :)

绝对路径与相对路径

有两种指定文件路径的方式。

- 绝对路径,它总是以根文件夹开头
- 相对路径,它相对于程序的当前工作目录

还有点 (.) 和点点 (..) 文件夹。它们不是真正的文件夹,而是可以在路径中使用的特殊名称。单个句点(“点”)表示“此目录”的简写。两个句点(“点点”)表示“父文件夹”。

处理绝对路径

要使用 pathlib 查看路径是否为绝对路径:

python
from pathlib import Path
Path('/').is_absolute()

output
True

python
Path('..').is_absolute()

output
False

<BaseQuiz id="cheatsheet-file-directory-path-2" correct="A">
<template #question>
<code>Path('/').is_absolute()</code> 返回什么?
</template>

<BaseQuizOption value="A" correct>A. <code>True</code></BaseQuizOption>
<BaseQuizOption value="B">B. <code>False</code></BaseQuizOption>
<BaseQuizOption value="C">C. <code>None</code></BaseQuizOption>
<BaseQuizOption value="D">D. <code>'/'</code></BaseQuizOption>
<BaseQuizAnswer><code>is_absolute()</code> 方法对绝对路径(在 Unix 上以 <code>/</code> 开头或在 Windows 上以驱动器号开头的路径)返回 <code>True</code>。</BaseQuizAnswer>
</BaseQuiz>

您可以使用 pathlib 提取绝对路径:

python
from pathlib import Path
print(Path.cwd())

output
/home/labex/project

python
print(Path('..').resolve())

output
/home

处理相对路径

您可以使用 pathlib 从起始路径获取到另一路径的相对路径:

python
from pathlib import Path
print(Path('/etc/passwd').relative_to('/'))

output
etc/passwd

路径和文件有效性

检查文件/目录是否存在

在 \*nix 上使用 pathlib

python
from pathlib import Path

Path('.').exists()

output
True

python
Path('setup.py').exists()

output
True

python
Path('/etc').exists()

output
True

python
Path('nonexistentfile').exists()

output
False

检查路径是否为文件

在 \*nix 上使用 pathlib

python
from pathlib import Path

Path('setup.py').is_file()

output
True

python
Path('/home').is_file()

output
False

python
Path('nonexistentfile').is_file()

output
False

<BaseQuiz id="cheatsheet-file-directory-path-3" correct="C">
<template #question>
如果 setup.py 存在,<code>Path('setup.py').is_file()</code> 将返回什么?
</template>

<BaseQuizOption value="A">A. <code>'setup.py'</code></BaseQuizOption>
<BaseQuizOption value="B">B. <code>False</code></BaseQuizOption>
<BaseQuizOption value="C" correct>C. <code>True</code></BaseQuizOption>
<BaseQuizOption value="D">D. <code>None</code></BaseQuizOption>
<BaseQuizAnswer><code>is_file()</code> 方法在路径存在且是文件时返回 <code>True</code>,否则返回 <code>False</code>。</BaseQuizAnswer>
</BaseQuiz>

检查路径是否为目录

在 \*nix 上使用 pathlib

python
from pathlib import Path

Path('/').is_dir()

output
True

python
Path('setup.py').is_dir()

output
False

python
Path('/spam').is_dir()

output
False

获取文件大小(以字节为单位)

在 \*nix 上使用 pathlib

python
from pathlib import Path

stat = Path('/bin/python3.6').stat()
print(stat) # stat 还包含有关文件的其他信息

output
os.stat_result(st_mode=33261, st_ino=141087, st_dev=2051, st_nlink=2, st_uid=0,
--snip--
st_gid=0, st_size=10024, st_atime=1517725562, st_mtime=1515119809, st_ctime=1517261276)

python
print(stat.st_size) # 以字节为单位的大小

output
10024

列出目录

在 \*nix 上使用 pathlib 列出目录内容:

python
from pathlib import Path

for f in Path('/usr/bin').iterdir():
print(f)

output
...
/usr/bin/tiff2rgba
/usr/bin/iconv
/usr/bin/ldd
/usr/bin/cache_restore
/usr/bin/udiskie
/usr/bin/unix2dos
/usr/bin/t1reencode
/usr/bin/epstopdf
/usr/bin/idle3
...

目录文件大小

<base-warning>
<base-warning-title>
警告
</base-warning-title>
<base-warning-content>
目录本身也有大小!因此,您可能需要使用上面讨论的方法中的方法来检查路径是文件还是目录。
</base-warning-content>
</base-warning>

在 \*nix 上使用 pathlib

python
from pathlib import Path

total_size = 0
for sub_path in Path('/usr/bin').iterdir():
total_size += sub_path.stat().st_size

print(total_size)

output
1903178911

复制文件和文件夹

shutil 模块提供了用于复制文件以及整个文件夹的函数。

python
import shutil

shutil.copy('/tmp/spam.txt', '/tmp/delicious')

output
/tmp/delicious/spam.txt

python
shutil.copy('/tmp/eggs.txt', '/tmp/delicious/eggs2.txt')

output
/tmp/delicious/eggs2.txt

<BaseQuiz id="cheatsheet-file-directory-path-4" correct="D">
<template #question>
您应该使用哪个函数来复制整个目录树,包括所有子目录和文件?
</template>

<BaseQuizOption value="A">A. <code>shutil.copy()</code></BaseQuizOption>
<BaseQuizOption value="B">B. <code>Path.copy()</code></BaseQuizOption>
<BaseQuizOption value="C">C. <code>os.copy()</code></BaseQuizOption>
<BaseQuizOption value="D" correct>D. <code>shutil.copytree()</code></BaseQuizOption>
<BaseQuizAnswer><code>shutil.copytree()</code> 函数递归地复制整个目录树,而 <code>shutil.copy()</code> 只复制单个文件。</BaseQuizAnswer>
</BaseQuiz>

虽然 shutil.copy() 会复制单个文件,但 shutil.copytree() 会复制整个文件夹及其包含的所有文件夹和文件:

python
import shutil

shutil.copytree('/tmp/bacon', '/tmp/bacon_backup')

output
/tmp/bacon_backup

移动和重命名

python
import shutil

shutil.move('/tmp/bacon.txt', '/tmp/eggs')

output
/tmp/eggs/bacon.txt

目标路径也可以指定文件名。在以下示例中,源文件被移动并重命名:

python
shutil.move('/tmp/bacon.txt', '/tmp/eggs/new_bacon.txt')

output
/tmp/eggs/new_bacon.txt

如果不存在 eggs 文件夹,则 move() 会将 bacon.txt 重命名为名为 eggs 的文件:

python
shutil.move('/tmp/bacon.txt', '/tmp/eggs')

output
/tmp/eggs

删除文件和文件夹

- 调用 Path.unlink() 将删除路径处的文件
- 调用 Path.rmdir() 将删除路径处的文件夹。此文件夹必须为空,不包含任何文件或文件夹。
- 调用 shutil.rmtree(path) 将删除路径处的文件夹,以及其中包含的所有文件和文件夹。

<BaseQuiz id="cheatsheet-file-directory-path-5" correct="B">
<template #question>
哪个方法可以删除非空目录及其所有内容?
</template>

<BaseQuizOption value="A">A. <code>Path.rmdir()</code></BaseQuizOption>
<BaseQuizOption value="B" correct>B. <code>shutil.rmtree()</code></BaseQuizOption>
<BaseQuizOption value="C">C. <code>Path.unlink()</code></BaseQuizOption>
<BaseQuizOption value="D">D. <code>os.remove()</code></BaseQuizOption>
<BaseQuizAnswer><code>shutil.rmtree()</code> 函数可以递归地删除目录及其所有内容。<code>Path.rmdir()</code> 仅适用于空目录。</BaseQuizAnswer>
</BaseQuiz>

遍历目录树

Path 对象有一个 rglob() 方法,用于递归迭代文件和目录。

python
from pathlib import Path

p = Path('/tmp/delicious')
for i in p.rglob('*'):
print(i)

output
/tmp/delicious/cats
/tmp/delicious/walnut
/tmp/delicious/spam.txt
/tmp/delicious/cats/catnames.txt
/tmp/delicious/cats/zophie.jpg
/tmp/delicious/walnut/waffles
/tmp/delicious/walnut/waffles/butter.txt

相关链接

- <router-link to="/cheatsheet/reading-and-writing-files">读取和写入文件</router-link>
- <router-link to="/blog/python-pathlib-essentials">每位开发者都应知道的 10 个基本文件系统操作</router-link>
- <router-link to="/builtin/open">open()</router-link>

---

Cheatsheet/Zh/Functions

---
title: 'Python 函数 - Python 速查表'
description: '在 Python 中,函数是一段组织良好的代码块,用于执行单个任务。'
labUrl: 'https://labex.io/zh/labs/python-python-functions-633658?course=python-cheatsheet'
---

<base-title :title="frontmatter.title" :description="frontmatter.description">
Python 函数
</base-title>

<base-lab-url :url="frontmatter.labUrl" />

<base-disclaimer>
<base-disclaimer-title>
<a target="_blank" href="https://en.wikiversity.org/wiki/Programming_Fundamentals/Functions">编程函数</a>
</base-disclaimer-title>
<base-disclaimer-content>
函数是一个组织良好的代码块,用于执行单个任务。它们为您的应用程序提供了更好的模块化和可重用性。
</base-disclaimer-content>
</base-disclaimer>

函数参数

函数可以接受 参数返回值

在下面的示例中,函数 say_hello 接收参数 "name" 并打印问候语:

python

定义一个接受一个参数的函数


def say_hello(name):
print(f'Hello {name}')

使用字符串参数调用函数


say_hello('Carlos')

output
Hello Carlos

python
say_hello('Wanda')

output
Hello Wanda

python
say_hello('Rose')

output
Hello Rose

关键字参数

为了提高代码的可读性,我们应该尽可能明确。我们可以通过使用 关键字参数 在函数中实现这一点:

python

带有多个参数的函数


def say_hi(name, greeting):
print(f"{greeting} {name}")

位置参数:顺序很重要


say_hi('John', 'Hello')

output
Hello John

python

关键字参数:顺序不重要,更具可读性


say_hi(name='Anna', greeting='Hi')

output
Hi Anna

<BaseQuiz id="cheatsheet-functions-1" correct="C">
<template #question>
在 Python 函数中使用关键字参数的主要优点是什么?
</template>

<BaseQuizOption value="A">A. 它们执行得更快</BaseQuizOption>
<BaseQuizOption value="B">B. 它们使用的内存更少</BaseQuizOption>
<BaseQuizOption value="C" correct>C. 它们提高了代码的可读性,并且顺序不重要</BaseQuizOption>
<BaseQuizOption value="D">D. 它们可以防止错误</BaseQuizOption>
<BaseQuizAnswer>关键字参数通过使每个参数的含义清晰来提高代码的可读性,并且允许您以任何顺序传递参数。</BaseQuizAnswer>
</BaseQuiz>

返回值

在使用 def 语句创建函数时,您可以使用 return 语句指定返回值是什么。返回语句包括以下内容:

- return 关键字。

- 函数应返回的值或表达式。

python

使用 return 语句返回一个值的函数


def sum_two_numbers(number_1, number_2):
return number_1 + number_2

调用函数并存储返回的值


result = sum_two_numbers(7, 8)
print(result)

output
15

<BaseQuiz id="cheatsheet-functions-2" correct="A">
<template #question>
在 Python 中,使用哪个关键字从函数中返回一个值?
</template>

<BaseQuizOption value="A" correct>A. <code>return</code></BaseQuizOption>
<BaseQuizOption value="B">B. <code>output</code></BaseQuizOption>
<BaseQuizOption value="C">C. <code>yield</code></BaseQuizOption>
<BaseQuizOption value="D">D. <code>exit</code></BaseQuizOption>
<BaseQuizAnswer>使用 <code>return</code> 关键字从函数返回一个值。如果未使用 return 语句,函数将返回 <code>None</code>。</BaseQuizAnswer>
</BaseQuiz>

局部和全局作用域

- 全局作用域中的代码不能使用任何局部变量。

- 但是,局部作用域可以访问全局变量。

- 函数的局部作用域中的代码不能使用任何其他局部作用域中的变量。

- 您可以使用相同的名称定义不同的变量,如果它们位于不同的作用域中。也就是说,可以有一个名为 spam 的局部变量和一个也名为 spam 的全局变量。

python

全局变量:随处可访问


global_variable = 'I am available everywhere'

def some_function():
print(global_variable) # 可以访问全局变量
# 局部变量:仅在此函数内存在
local_variable = "only available within this function"
print(local_variable)

这将引发 NameError:local_variable 在全局作用域中不存在


print(local_variable)

output
Traceback (most recent call last):
File "<stdin>", line 10, in <module>
NameError: name 'local_variable' is not defined

global 语句

如果您需要在函数内部修改全局变量,请使用 global 语句:

python

使用 'global' 关键字从函数内部修改全局变量


def spam():
global eggs # 声明我们将修改全局变量
eggs = 'spam' # 这会更改全局变量

eggs = 'global'
spam() # 函数修改全局变量
print(eggs) # 打印 'spam',而不是 'global'

output
spam

<BaseQuiz id="cheatsheet-functions-3" correct="B">
<template #question>
在函数内部,您必须使用哪个关键字来修改全局变量?
</template>

<BaseQuizOption value="A">A. <code>nonlocal</code></BaseQuizOption>
<BaseQuizOption value="B" correct>B. <code>global</code></BaseQuizOption>
<BaseQuizOption value="C">C. <code>extern</code></BaseQuizOption>
<BaseQuizOption value="D">D. 不需要关键字</BaseQuizOption>
<BaseQuizAnswer>必须在函数内部使用 <code>global</code> 关键字来修改全局变量。如果没有它,Python 将创建一个局部变量。</BaseQuizAnswer>
</BaseQuiz>

判断变量是在局部作用域还是全局作用域有四个规则:

1. 如果一个变量在全局作用域中使用(即在所有函数之外),那么它总是全局变量。

1. 如果函数中存在该变量的全局语句,则它是全局变量。

1. 否则,如果该变量在函数中的赋值语句中使用,则它是局部变量。

1. 但如果该变量在赋值语句中未使用,则它是全局变量。

Lambda 函数

在 Python 中,lambda 函数是单行、匿名函数,可以有任意数量的参数,但只能有一个表达式。

<base-disclaimer>
<base-disclaimer-title>
来自 <a target="_blank" href="https://docs.python.org/3/library/ast.html?highlight=lambda#function-and-class-definitions">Python 3 教程</a>
</base-disclaimer-title>
<base-disclaimer-content>
lambda 是一个最小函数定义,可以在表达式中使用。与 FunctionDef 不同,body 包含单个节点。
</base-disclaimer-content>
</base-disclaimer>

<base-warning>
<base-warning-title>
单行表达式
</base-warning-title>
<base-warning-content>
Lambda 函数只能评估一个表达式,例如单行代码。
</base-warning-content>
</base-warning>

这个函数:

python

常规函数定义


def add(x, y):
return x + y

add(5, 3)

output
8

等同于 _lambda_ 函数:

python

Lambda 函数:在一行中定义的匿名函数


语法:lambda arguments: expression


add = lambda x, y: x + y
add(5, 3)

output
8

<BaseQuiz id="cheatsheet-functions-4" correct="D">
<template #question>
Python 中的 lambda 函数是什么?
</template>

<BaseQuizOption value="A">A. 只能调用一次的函数</BaseQuizOption>
<BaseQuizOption value="B">B. 不接受任何参数的函数</BaseQuizOption>
<BaseQuizOption value="C">C. 返回多个值的函数</BaseQuizOption>
<BaseQuizOption value="D" correct>D. 可以有任意数量的参数但只有一个表达式的单行匿名函数</BaseQuizOption>
<BaseQuizAnswer>Lambda 函数是使用 <code>lambda</code> 关键字定义的匿名、单行函数。它可以接受任意数量的参数,但只能包含一个表达式。</BaseQuizAnswer>
</BaseQuiz>

与常规嵌套函数一样,lambda 也可以作为词法闭包:

python

Lambda 闭包:从外部作用域捕获变量的 lambda 函数


def make_adder(n):
return lambda x: x + n # Lambda 从外部函数捕获 'n'

创建添加不同数量的函数


plus_3 = make_adder(3) # 返回一个加 3 的 lambda
plus_5 = make_adder(5) # 返回一个加 5 的 lambda

plus_3(4) # 返回 4 + 3 = 7

output
7

python
plus_5(4)

output
9

<BaseQuiz id="cheatsheet-functions-5" correct="A">
<template #question>
Lambda 闭包允许您做什么?
</template>

<BaseQuizOption value="A" correct>A. 从外部作用域捕获变量</BaseQuizOption>
<BaseQuizOption value="B">B. 在不使用 global 关键字的情况下修改全局变量</BaseQuizOption>
<BaseQuizOption value="C">C. 返回多个值</BaseQuizOption>
<BaseQuizOption value="D">D. 异步执行代码</BaseQuizOption>
<BaseQuizAnswer>Lambda 闭包允许 lambda 函数捕获并使用其封闭作用域中的变量,类似于常规的嵌套函数。</BaseQuizAnswer>
</BaseQuiz>

相关链接

- <router-link to="/blog/python-easy-args-kwargs">\args 和 \\*kwargs 解释</router-link>
- <router-link to="/cheatsheet/args-and-kwargs">Args 和 Kwargs</router-link>
- <router-link to="/cheatsheet/decorators">装饰器</router-link>
- <router-link to="/cheatsheet/control-flow">控制流</router-link>
- <router-link to="/cheatsheet/basics">基础知识</router-link>
- <router-link to="/builtin">内置函数</router-link>

---

Cheatsheet/Zh/Json Yaml

---
title: 'Python JSON 与 YAML - Python 速查表'
description: 'JSON(JavaScript 对象表示法)是一种轻量级的数据存储和传输格式。当数据从服务器发送到网页时,JSON 经常被使用。'
labUrl: 'https://labex.io/zh/labs/python-python-json-and-yaml-633659?course=python-cheatsheet'
---

<base-title :title="frontmatter.title" :description="frontmatter.description">
JSON 和 YAML
</base-title>

<base-lab-url :url="frontmatter.labUrl" />

JSON

JSON 代表 JavaScript Object Notation,是一种用于存储和传输数据的轻量级格式。当数据从服务器发送到网页时,通常会使用 JSON。

python

读取 JSON 文件:json.load() 从文件对象解析 JSON


import json
with open("filename.json", "r") as f: # 以读取模式打开文件
content = json.load(f) # 解析 JSON 并返回 Python 字典/列表

写入包含以下内容的 JSON 文件:

python

写入 JSON 文件:json.dump() 将 Python 对象写入 JSON


import json

content = {"name": "Joe", "age": 20}
with open("filename.json", "w") as f: # 以写入模式打开文件
json.dump(content, f, indent=2) # 写入 JSON,使用 2 个空格缩进

<BaseQuiz id="cheatsheet-json-yaml-1" correct="B">
<template #question>
哪个函数用于将 Python 字典写入 JSON 文件?
</template>

<BaseQuizOption value="A">A. <code>json.write()</code></BaseQuizOption>
<BaseQuizOption value="B" correct>B. <code>json.dump()</code></BaseQuizOption>
<BaseQuizOption value="C">C. <code>json.save()</code></BaseQuizOption>
<BaseQuizOption value="D">D. <code>json.export()</code></BaseQuizOption>
<BaseQuizAnswer><code>json.dump()</code> 函数将 Python 对象(如字典)写入 JSON 文件。<code>json.load()</code> 用于读取 JSON 文件。</BaseQuizAnswer>
</BaseQuiz>

YAML

与 JSON 相比,YAML 具有更好的人类可维护性,并提供了添加注释的能力。对于需要人工编辑的配置文件来说,它是一个方便的选择。

允许访问 YAML 文件的主要库有两个:

- PyYaml
- Ruamel.yaml

在您的虚拟环境中,使用 pip install 安装它们。

第一个更容易使用,但第二个 Ruamel 更好地实现了 YAML 规范,并允许例如在不更改注释的情况下修改 YAML 内容。

使用以下方法打开 YAML 文件:

python

使用 ruamel.yaml 库读取 YAML 文件


from ruamel.yaml import YAML

with open("filename.yaml") as f:
yaml=YAML() # 创建 YAML 解析器实例
yaml.load(f) # 解析 YAML 并返回 Python 字典/列表

<BaseQuiz id="cheatsheet-json-yaml-2" correct="C">
<template #question>
YAML 相对于 JSON 的一个优点是什么?
</template>

<BaseQuizOption value="A">A. YAML 文件更小</BaseQuizOption>
<BaseQuizOption value="B">B. YAML 解析速度更快</BaseQuizOption>
<BaseQuizOption value="C" correct>C. YAML 允许注释且更易于人类阅读</BaseQuizOption>
<BaseQuizOption value="D">D. YAML 是 Python 内置的</BaseQuizOption>
<BaseQuizAnswer>YAML 允许注释,并且比 JSON 更易于人类阅读,使其成为需要人工编辑的配置文件的方便选择。</BaseQuizAnswer>
</BaseQuiz>

Anyconfig

Anyconfig 是一个非常方便的包,它允许完全抽象底层配置文件格式。它可以从 JSON、YAML、TOML 等加载 Python 字典。

使用以下命令安装它:

bash
pip install anyconfig

用法:

python

anyconfig: 以各种格式(JSON、YAML、TOML 等)加载配置文件


import anyconfig
conf1 = anyconfig.load("/path/to/foo/conf.d/a.yml") # 自动检测格式

<BaseQuiz id="cheatsheet-json-yaml-3" correct="A">
<template #question>
anyconfig 库允许您做什么?
</template>

<BaseQuizOption value="A" correct>A. 以各种格式(JSON、YAML、TOML)加载配置文件,而无需指定格式</BaseQuizOption>
<BaseQuizOption value="B">B. 在不同配置格式之间转换</BaseQuizOption>
<BaseQuizOption value="C">C. 验证配置文件语法</BaseQuizOption>
<BaseQuizOption value="D">D. 加密配置文件</BaseQuizOption>
<BaseQuizAnswer>anyconfig 库抽象了底层配置文件格式,允许您从 JSON、YAML、TOML 等格式加载 Python 字典,而无需知道正在使用的具体格式。</BaseQuizAnswer>
</BaseQuiz>

相关链接

- <router-link to="/cheatsheet/reading-and-writing-files">读取和写入文件</router-link>
- <router-link to="/cheatsheet/dictionaries">Python 字典</router-link>
- <router-link to="/modules/json-module">json 模块</router-link>
- <router-link to="/blog/python-pathlib-essentials">每位开发者都应知道的 10 个基本文件系统操作</router-link>
- <router-link to="/builtin/open">open()</router-link>
- <router-link to="/builtin/dict">dict()</router-link>

---

Cheatsheet/Zh/Lists And Tuples

---
title: 'Python 列表与元组 - Python 速查表'
description: '在 Python 中,列表是用于存储数据集合的四种数据类型之一。'
labUrl: 'https://labex.io/zh/labs/python-python-lists-and-tuples-633660?course=python-cheatsheet'
---

<base-title :title="frontmatter.title" :description="frontmatter.description">
Python 列表
</base-title>

<base-lab-url :url="frontmatter.labUrl" />

列表是 Python 中用于存储数据集合的 4 种数据类型之一。

python

List: 有序的项目集合,用方括号括起来


['John', 'Peter', 'Debora', 'Charles']

使用索引获取值

python

使用索引访问列表元素(从 0 开始,第一个元素是索引 0)


furniture = ['table', 'chair', 'rack', 'shelf']

furniture[0] # 返回第一个元素:'table'

output
'table'

python
furniture[1]

output
'chair'

python
furniture[2]

output
'rack'

python
furniture[3]

output
'shelf'

负数索引

python

负数索引:从列表末尾访问元素


furniture = ['table', 'chair', 'rack', 'shelf']

furniture[-1] # 返回最后一个元素:'shelf'

output
'shelf'

python
furniture[-3]

output
'chair'

python
f'The {furniture[-1]} is bigger than the {furniture[-3]}'

output
'The shelf is bigger than the chair'

<BaseQuiz id="cheatsheet-lists-and-tuples-1" correct="B">
<template #question>
如果 <code>furniture = ['table', 'chair', 'rack', 'shelf']</code>,那么 <code>furniture[-1]</code> 返回什么?
</template>

<BaseQuizOption value="A">A. <code>'table'</code></BaseQuizOption>
<BaseQuizOption value="B" correct>B. <code>'shelf'</code></BaseQuizOption>
<BaseQuizOption value="C">C. <code>['shelf']</code></BaseQuizOption>
<BaseQuizOption value="D">D. <code>IndexError</code></BaseQuizOption>
<BaseQuizAnswer>负数索引从列表末尾访问元素。<code>-1</code> 指向最后一个元素,<code>-2</code> 指向倒数第二个,依此类推。</BaseQuizAnswer>
</BaseQuiz>

使用切片获取子列表

python

切片:使用 [start:end] 语法获取子列表(end 是不包含的)


furniture = ['table', 'chair', 'rack', 'shelf']

furniture[0:4] # 返回索引 0 到 3 的元素(不包含 4)

output
['table', 'chair', 'rack', 'shelf']

python
furniture[1:3]

output
['chair', 'rack']

python
furniture[0:-1]

output
['table', 'chair', 'rack']

python

从开头切片:省略 start 索引(默认为 0)


furniture[:2] # 返回前两个元素

output
['table', 'chair']

python

切片到末尾:省略 end 索引(默认为列表末尾)


furniture[1:] # 返回从索引 1 到末尾的所有元素

output
['chair', 'rack', 'shelf']

python
furniture[:]

output
['table', 'chair', 'rack', 'shelf']

切片整个列表将执行复制:

python

切片创建副本:[:] 创建列表的浅拷贝


spam = ['cat', 'bat', 'rat', 'elephant']
spam2 = spam[:] # 创建一个副本,而不是引用
spam2

output
['cat', 'bat', 'rat', 'elephant']

python
spam.append('dog')
spam

output
['cat', 'bat', 'rat', 'elephant', 'dog']

python
spam2

output
['cat', 'bat', 'rat', 'elephant']

<BaseQuiz id="cheatsheet-lists-and-tuples-2" correct="C">
<template #question>
当 <code>spam</code> 是一个列表时,<code>spam[:]</code> 创建什么?
</template>

<BaseQuizOption value="A">A. 对同一列表的引用</BaseQuizOption>
<BaseQuizOption value="B">B. 一个空列表</BaseQuizOption>
<BaseQuizOption value="C" correct>C. 列表的浅拷贝</BaseQuizOption>
<BaseQuizOption value="D">D. 一个反转的列表</BaseQuizOption>
<BaseQuizAnswer>使用 <code>[:]</code> 对整个列表进行切片会创建一个浅拷贝。修改副本不会影响原始列表。</BaseQuizAnswer>
</BaseQuiz>

使用 len() 获取列表长度

python

len() 返回列表中项目的数量


furniture = ['table', 'chair', 'rack', 'shelf']
len(furniture) # 返回 4

output
4

使用索引更改值

python

通过向索引分配新值来修改列表元素


furniture = ['table', 'chair', 'rack', 'shelf']

furniture[0] = 'desk' # 替换第一个元素
furniture

output
['desk', 'chair', 'rack', 'shelf']

python
furniture[2] = furniture[1]
furniture

output
['desk', 'chair', 'chair', 'shelf']

python
furniture[-1] = 'bed'
furniture

output
['desk', 'chair', 'chair', 'bed']

拼接和复制

python

列表拼接:使用 + 运算符组合两个列表


[1, 2, 3] + ['A', 'B', 'C'] # 返回 [1, 2, 3, 'A', 'B', 'C']

output
[1, 2, 3, 'A', 'B', 'C']

python

列表复制:使用 * 运算符多次重复列表


['X', 'Y', 'Z'] * 3 # 返回 ['X', 'Y', 'Z', 'X', 'Y', 'Z', 'X', 'Y', 'Z']

output
['X', 'Y', 'Z', 'X', 'Y', 'Z', 'X', 'Y', 'Z']

python
my_list = [1, 2, 3]
my_list = my_list + ['A', 'B', 'C']
my_list

output
[1, 2, 3, 'A', 'B', 'C']

使用 for 循环处理列表

python

使用 for 循环遍历列表元素


furniture = ['table', 'chair', 'rack', 'shelf']

for item in furniture: # 遍历每个项目
print(item)

output
table
chair
rack
shelf

使用 enumerate() 在循环中获取索引

python

enumerate() 在循环中同时返回索引和值


furniture = ['table', 'chair', 'rack', 'shelf']

for index, item in enumerate(furniture): # 一起获取索引和项目
print(f'index: {index} - item: {item}')

output
index: 0 - item: table
index: 1 - item: chair
index: 2 - item: rack
index: 3 - item: shelf

使用 zip() 在多个列表中循环

python

zip() 按元素将多个列表组合在一起进行循环


furniture = ['table', 'chair', 'rack', 'shelf']
price = [100, 50, 80, 40]

for item, amount in zip(furniture, price): # 配对两个列表中的元素
print(f'The {item} costs ${amount}')

output
The table costs $100
The chair costs $50
The rack costs $80
The shelf costs $40

in 和 not in 运算符

python

in 运算符:检查一个项目是否存在于列表中


'rack' in ['table', 'chair', 'rack', 'shelf'] # 返回 True

output
True

python
'bed' in ['table', 'chair', 'rack', 'shelf']

output
False

python
furniture = ['table', 'chair', 'rack', 'shelf']
'bed' not in furniture

output
True

python
'rack' not in furniture

output
False

多重赋值技巧

多重赋值技巧是一种快捷方式,允许您在一行代码中用列表中的值给多个变量赋值。所以,与其这样做:

python
furniture = ['table', 'chair', 'rack', 'shelf']
table = furniture[0]
chair = furniture[1]
rack = furniture[2]
shelf = furniture[3]

您可以输入这一行代码:

python
furniture = ['table', 'chair', 'rack', 'shelf']
table, chair, rack, shelf = furniture

table

output
'table'

python
chair

output
'chair'

python
rack

output
'rack'

python
shelf

output
'shelf'

多重赋值技巧也可以用来交换两个变量的值:

python
a, b = 'table', 'chair'
a, b = b, a
print(a)

output
chair

python
print(b)

output
table

index 方法

index 方法允许您通过传递其名称来查找值的索引:

python
furniture = ['table', 'chair', 'rack', 'shelf']
furniture.index('chair')

output
1

添加值

append()

append 将一个元素添加到 list 的末尾:

python
furniture = ['table', 'chair', 'rack', 'shelf']
furniture.append('bed')
furniture

output
['table', 'chair', 'rack', 'shelf', 'bed']

<BaseQuiz id="cheatsheet-lists-and-tuples-3" correct="A">
<template #question>
<code>append()</code> 方法对列表做什么?
</template>

<BaseQuizOption value="A" correct>A. 将一个元素添加到列表的末尾</BaseQuizOption>
<BaseQuizOption value="B">B. 将一个元素添加到列表的开头</BaseQuizOption>
<BaseQuizOption value="C">C. 替换最后一个元素</BaseQuizOption>
<BaseQuizOption value="D">D. 移除最后一个元素</BaseQuizOption>
<BaseQuizAnswer><code>append()</code> 方法将单个元素添加到列表的末尾。要将元素添加到特定位置,请使用 <code>insert()</code>。</BaseQuizAnswer>
</BaseQuiz>

insert()

insert 在给定位置向 list 添加一个元素:

python
furniture = ['table', 'chair', 'rack', 'shelf']
furniture.insert(1, 'bed')
furniture

output
['table', 'bed', 'chair', 'rack', 'shelf']

移除值

del

del 使用索引移除一个项:

python
furniture = ['table', 'chair', 'rack', 'shelf']
del furniture[2]
furniture

output
['table', 'chair', 'shelf']

python
del furniture[2]
furniture

output
['table', 'chair']

remove()

remove 使用其实际值移除一个项:

python
furniture = ['table', 'chair', 'rack', 'shelf']
furniture.remove('chair')
furniture

output
['table', 'rack', 'shelf']

<base-warning>
<base-warning-title>
移除重复项
</base-warning-title>
<base-warning-content>
如果该值在列表中出现多次,则只移除该值的第一个实例。
</base-warning-content>
</base-warning>

pop()

默认情况下,pop 将移除并返回列表的最后一个项。您也可以将元素的索引作为可选参数传递:

python
animals = ['cat', 'bat', 'rat', 'elephant']

animals.pop()

output
'elephant'

python
animals

output
['cat', 'bat', 'rat']

python
animals.pop(0)

output
'cat'

python
animals

output
['bat', 'rat']

<BaseQuiz id="cheatsheet-lists-and-tuples-4" correct="B">
<template #question>
调用列表上的 <code>pop()</code> 会做什么?
</template>

<BaseQuizOption value="A">A. 只移除最后一项</BaseQuizOption>
<BaseQuizOption value="B" correct>B. 移除并返回一项(默认最后一个,或指定的索引)</BaseQuizOption>
<BaseQuizOption value="C">C. 只返回最后一项而不移除它</BaseQuizOption>
<BaseQuizOption value="D">D. 移除列表中的所有项</BaseQuizOption>
<BaseQuizAnswer><code>pop()</code> 方法会移除并返回一项。默认情况下它移除最后一项,但您可以传递一个索引来移除特定项。</BaseQuizAnswer>
</BaseQuiz>

使用 sort() 对值进行排序

python
numbers = [2, 5, 3.14, 1, -7]
numbers.sort()
numbers

output
[-7, 1, 2, 3.14, 5]

python
furniture = ['table', 'chair', 'rack', 'shelf']
furniture.sort()
furniture

output
['chair', 'rack', 'shelf', 'table']

您也可以为 reverse 关键字参数传递 True,以便 sort() 以相反的顺序对值进行排序:

python
furniture.sort(reverse=True)
furniture

output
['table', 'shelf', 'rack', 'chair']

如果您需要按常规字母顺序对值进行排序,请在 sort() 方法调用中为 key 关键字参数传递 str.lower

python
letters = ['a', 'z', 'A', 'Z']
letters.sort(key=str.lower)
letters

output
['a', 'A', 'z', 'Z']

您可以使用内置函数 sorted 来返回一个新列表:

python
furniture = ['table', 'chair', 'rack', 'shelf']
sorted(furniture)

output
['chair', 'rack', 'shelf', 'table']

Tuple 数据类型

<base-disclaimer>
<base-disclaimer-title>
<a target="_blank" href="https://stackoverflow.com/questions/1708510/list-vs-tuple-when-to-use-each">元组与列表</a>
</base-disclaimer-title>
<base-disclaimer-content>
元组和列表之间的关键区别在于,<code>元组</code>是<i>不可变</i>对象,而<code>列表</code>是<i>可变</i>对象。这意味着元组不能被更改,而列表可以被修改。元组比列表更节省内存。
</base-disclaimer-content>
</base-disclaimer>

python
furniture = ('table', 'chair', 'rack', 'shelf')

furniture[0]

output
'table'

python
furniture[1:3]

output
('chair', 'rack')

python
len(furniture)

output
4

元组与列表的主要区别在于,元组像字符串一样是不可变的。

在 list() 和 tuple() 之间转换

python
tuple(['cat', 'dog', 5])

output
('cat', 'dog', 5)

python
list(('cat', 'dog', 5))

output
['cat', 'dog', 5]

python
list('hello')

output
['h', 'e', 'l', 'l', 'o']

<BaseQuiz id="cheatsheet-lists-and-tuples-5" correct="C">
<template #question>
Python 中列表和元组的主要区别是什么?
</template>

<BaseQuizOption value="A">A. 列表只能包含数字,元组可以包含任何内容</BaseQuizOption>
<BaseQuizOption value="B">B. 元组创建速度更快</BaseQuizOption>
<BaseQuizOption value="C" correct>C. 列表是可变的(可以更改),元组是不可变的(不能更改)</BaseQuizOption>
<BaseQuizOption value="D">D. 列表使用方括号,元组使用花括号</BaseQuizOption>
<BaseQuizAnswer>列表是可变的,意味着您可以在创建后修改它们。元组是不可变的,意味着一旦创建就不能更改。两者都可以包含任何类型的数据。</BaseQuizAnswer>
</BaseQuiz>

相关链接

- <router-link to="/blog/python-data-types">Python 数据类型:初学者视觉指南</router-link>
- <router-link to="/blog/python-comprehensions-step-by-step">Python 推导式分步指南</router-link>
- <router-link to="/cheatsheet/comprehensions">Python 推导式</router-link>
- <router-link to="/modules/itertools-module">itertools 模块</router-link>
- <router-link to="/builtin/list">list()</router-link>
- <router-link to="/builtin/tuple">tuple()</router-link>
- <router-link to="/builtin/len">len()</router-link>

---

Cheatsheet/Zh/Main

---
title: 'Python 主函数 - Python 速查表'
description: '是顶级代码执行范围的名称。当从标准输入、脚本或交互式提示符读取时,模块的名称被设置为 main。'
labUrl: 'https://labex.io/zh/labs/python-python-main-function-633661?course=python-cheatsheet'
---

<base-title :title="frontmatter.title" :description="frontmatter.description">
主顶层脚本环境
</base-title>

<base-lab-url :url="frontmatter.labUrl" />

是什么

__main__ 是顶层代码执行所在作用域的名称。
当一个模块从标准输入、脚本或交互式提示中读取时,其 name 被设置为等于 __main__

模块可以通过检查自身的 __name__ 来发现它是否在主作用域中运行,这允许使用一种常见的惯用法来有条件地执行模块中的代码。当它作为脚本运行或使用 python -m 运行时执行,但导入时不会:

python

__name__ == "__main__": 检查脚本是否被直接运行(未被导入)


if __name__ == "__main__": # 脚本运行时为 True,导入时为 False
# 仅在作为脚本运行时执行
main()

对于包而言,通过包含一个 main.py 模块可以实现相同效果,当使用 -m 运行该模块时,其内容将被执行。

例如,我们正在开发一个设计为用作模块的脚本,我们应该这样做:

python

示例:函数可以被导入,但测试代码仅在直接执行时运行


def add(a, b):
return a+b

if __name__ == "__main__": # 仅在文件被执行时运行,而不是被导入时运行
add(3, 5)

<BaseQuiz id="cheatsheet-main-1" correct="B">
<template #question>
当一个 Python 文件作为脚本直接运行时,<code>__name__</code> 的值是多少?
</template>

<BaseQuizOption value="A">A. 文件名</BaseQuizOption>
<BaseQuizOption value="B" correct>B. <code>"main"</code></BaseQuizOption>
<BaseQuizOption value="C">C. <code>None</code></BaseQuizOption>
<BaseQuizOption value="D">D. <code>True</code></BaseQuizOption>
<BaseQuizAnswer>当一个 Python 文件作为脚本直接运行时,<code>name</code> 被设置为 <code>"main"</code>。当文件被导入为一个模块时,<code>name</code> 被设置为模块的名称。</BaseQuizAnswer>
</BaseQuiz>

优点

1. 每个 Python 模块都有其定义的 __name__,如果它是 __main__,则意味着该模块是用户独立运行的,我们可以执行相应的适当操作。
2. 如果你将此脚本作为模块导入到另一个脚本中,name 将被设置为脚本/模块的名称。
3. Python 文件可以充当可重用的模块,也可以充当独立程序。
4. if __name__ == "__main__": 用于仅在文件被直接运行时执行某些代码,而不是在被导入时执行。

<BaseQuiz id="cheatsheet-main-2" correct="A">
<template #question>
使用 <code>if __name__ == "__main__":</code> 的主要目的是什么?
</template>

<BaseQuizOption value="A" correct>A. 仅在文件被直接运行时执行代码,而不是在被导入时执行</BaseQuizOption>
<BaseQuizOption value="B">B. 防止文件被导入</BaseQuizOption>
<BaseQuizOption value="C">C. 使文件执行速度更快</BaseQuizOption>
<BaseQuizOption value="D">D. 向其他模块隐藏代码</BaseQuizOption>
<BaseQuizAnswer><code>if name == "main":</code> 惯用法允许 Python 文件同时充当可重用的模块和独立程序。只有当文件被直接执行而不是被导入时,该代码块内的代码才会运行。</BaseQuizAnswer>
</BaseQuiz>

相关链接

- <router-link to="/cheatsheet/functions">函数</router-link>
- <router-link to="/cheatsheet/packaging">打包</router-link>
- <router-link to="/blog/python-projects-with-poetry-and-vscode-part-1">使用 Poetry 和 VSCode 的 Python 项目。第一部分</router-link>
- <router-link to="/builtin/import">import()</router-link>

---

Cheatsheet/Zh/Manipulating Strings

---
title: 'Python 字符串操作速查表'
description: "转义字符通过输入反斜杠 \ 后跟要插入的字符来创建。"
labUrl: 'https://labex.io/zh/labs/python-python-string-manipulation-633668?course=python-cheatsheet'
---

<base-title :title="frontmatter.title" :description="frontmatter.description">
操作字符串
</base-title>

<base-lab-url :url="frontmatter.labUrl" />

转义字符

转义字符是通过键入反斜杠 \ 后跟要插入的字符来创建的。

| 转义字符 | 打印为 |
| :------- | :------------- |
| \' | 单引号 |
| \" | 双引号 |
| \t | 制表符 |
| \n | 换行符(换行) |
| \\ | 反斜杠 |
| \b | 退格键 |
| \ooo | 八进制值 |
| \r | 回车 |

python

转义字符:使用反斜杠插入特殊字符


\n = 换行,\' = 单引号


print("Hello there!\nHow are you?\nI\'m doing fine.")

output
Hello there!
How are you?
I'm doing fine.

原始字符串

原始字符串完全忽略所有转义字符,并打印字符串中出现的任何反斜杠。

python

原始字符串(r 前缀):将反斜杠视为字面字符


print(r"Hello there!\nHow are you?\nI\'m doing fine.") # \n 按字面意思打印

output
Hello there!\nHow are you?\nI\'m doing fine.

原始字符串主要用于 <router-link to="/cheatsheet/regular-expressions">正则表达式</router-link> 定义。

<BaseQuiz id="cheatsheet-manipulating-strings-1" correct="B">
<template #question>
Python 中以 <code>r</code> 为前缀的原始字符串的作用是什么?
</template>

<BaseQuizOption value="A">A. 将所有字符转换为大写</BaseQuizOption>
<BaseQuizOption value="B" correct>B. 将反斜杠视为字面字符,忽略转义序列</BaseQuizOption>
<BaseQuizOption value="C">C. 移除所有空格</BaseQuizOption>
<BaseQuizOption value="D">D. 反转字符串</BaseQuizOption>
<BaseQuizAnswer>以 <code>r</code> 为前缀的原始字符串将反斜杠视为字面字符,因此 <code>\n</code> 等转义序列不会被解释。</BaseQuizAnswer>
</BaseQuiz>

多行字符串

python
print(
"""Dear Alice,

Eve's cat has been arrested for catnapping,
cat burglary, and extortion.

Sincerely,
Bob"""
)

output
Dear Alice,

Eve's cat has been arrested for catnapping,
cat burglary, and extortion.

Sincerely,
Bob

字符串的索引和切片

H e l l o w o r l d !
0 1 2 3 4 5 6 7 8 9 10 11

索引

python

字符串索引:通过位置(从 0 开始)访问字符


spam = 'Hello world!'

spam[0] # 返回第一个字符:'H'

output
'H'

python
spam[4]

output
'o'

python
spam[-1]

output
'!'

切片

python

字符串切片:使用 [start:end] 语法提取子字符串


spam = 'Hello world!'

spam[0:5] # 返回索引 0 到 4 的字符:'Hello'

output
'Hello'

python
spam[:5]

output
'Hello'

python
spam[6:]

output
'world!'

python
spam[6:-1]

output
'world'

python
spam[:-1]

output
'Hello world'

python
spam[::-1]

output
'!dlrow olleH'

<BaseQuiz id="cheatsheet-manipulating-strings-2" correct="C">
<template #question>
<code>spam[::-1]</code> 对字符串做什么?
</template>

<BaseQuizOption value="A">A. 返回第一个字符</BaseQuizOption>
<BaseQuizOption value="B">B. 返回最后一个字符</BaseQuizOption>
<BaseQuizOption value="C" correct>C. 反转字符串</BaseQuizOption>
<BaseQuizOption value="D">D. 移除所有字符</BaseQuizOption>
<BaseQuizAnswer>切片 <code>[::-1]</code> 通过向后遍历所有字符来反转字符串。<code>-1</code> 的步长值表示“向后移动”。</BaseQuizAnswer>
</BaseQuiz>

python
fizz = spam[0:5]
fizz

output
'Hello'

in 和 not in 运算符

python
'Hello' in 'Hello World'

output
True

python
'Hello' in 'Hello'

output
True

python
'HELLO' in 'Hello World'

output
False

python
'' in 'spam'

output
True

python
'cats' not in 'cats and dogs'

output
False

upper(), lower() 和 title()

将字符串转换为大写、小写和标题大小写:

python
greet = 'Hello world!'
greet.upper()

output
'HELLO WORLD!'

python
greet.lower()

output
'hello world!'

python
greet.title()

output
'Hello World!'

isupper() 和 islower() 方法

评估字符串是大写还是小写后返回 TrueFalse

python
spam = 'Hello world!'
spam.islower()

output
False

python
spam.isupper()

output
False

python
'HELLO'.isupper()

output
True

python
'abc12345'.islower()

output
True

python
'12345'.islower()

output
False

python
'12345'.isupper()

output
False

isX 字符串方法

| 方法 | 描述 |
| :---------- | :-------------------------------------------------------------------- |
| isalpha() | 如果字符串仅由字母组成,则返回 True。 |
| isalnum() | 如果字符串仅由字母和数字组成,则返回 True。 |
| isdecimal() | 如果字符串仅由数字组成,则返回 True。 |
| isspace() | 如果字符串仅由空格、制表符和换行符组成,则返回 True。 |
| istitle() | 如果字符串仅由以大写字母开头后跟仅小写字符的单词组成,则返回 True。 |

startswith() 和 endswith()

python
'Hello world!'.startswith('Hello')

output
True

python
'Hello world!'.endswith('world!')

output
True

python
'abc123'.startswith('abcdef')

output
False

python
'abc123'.endswith('12')

output
False

python
'Hello world!'.startswith('Hello world!')

output
True

python
'Hello world!'.endswith('Hello world!')

output
True

<BaseQuiz id="cheatsheet-manipulating-strings-3" correct="A">
<template #question>
<code>startswith()</code> 返回什么?
</template>

<BaseQuizOption value="A" correct>A. 如果字符串以指定的子字符串开头,则返回 <code>True</code>,否则返回 <code>False</code></BaseQuizOption>
<BaseQuizOption value="B">B. 匹配开头的子字符串</BaseQuizOption>
<BaseQuizOption value="C">C. 子字符串开始的索引</BaseQuizOption>
<BaseQuizOption value="D">D. 一个不带前缀的新字符串</BaseQuizOption>
<BaseQuizAnswer><code>startswith()</code> 方法返回一个布尔值:如果字符串以指定的子字符串开头,则返回 <code>True</code>,否则返回 <code>False</code>。</BaseQuizAnswer>
</BaseQuiz>

join() 和 split()

join()

join() 方法接受可迭代对象(如 <router-link to="/cheatsheet/lists-and-tuples">列表</router-link>、<router-link to="/cheatsheet/dictionaries">字典</router-link>、<router-link to="/cheatsheet/lists-and-tuples#the-tuple-data-type">元组</router-link> 或 <router-link to="/cheatsheet/sets">集合</router-link>)中的所有项,并将它们连接成一个字符串。您也可以指定一个分隔符。

python
''.join(['My', 'name', 'is', 'Simon'])

output
'MynameisSimon'

python
', '.join(['cats', 'rats', 'bats'])

output
'cats, rats, bats'

python
' '.join(['My', 'name', 'is', 'Simon'])

output
'My name is Simon'

python
'ABC'.join(['My', 'name', 'is', 'Simon'])

output
'MyABCnameABCisABCSimon'

split()

split() 方法将一个 string 分割成一个 list。默认情况下,它使用空格来分隔各项,但您也可以设置另一个选择的字符:

python
'My name is Simon'.split()

output
['My', 'name', 'is', 'Simon']

python
'MyABCnameABCisABCSimon'.split('ABC')

output
['My', 'name', 'is', 'Simon']

python
'My name is Simon'.split('m')

output
['My na', 'e is Si', 'on']

python
' My  name is  Simon'.split()

output
['My', 'name', 'is', 'Simon']

python
' My  name is  Simon'.split(' ')

output
['', 'My', '', 'name', 'is', '', 'Simon']

<BaseQuiz id="cheatsheet-manipulating-strings-4" correct="B">
<template #question>
对字符串调用 <code>split()</code> 会返回什么?
</template>

<BaseQuizOption value="A">A. 一个字符串</BaseQuizOption>
<BaseQuizOption value="B" correct>B. 一个字符串列表</BaseQuizOption>
<BaseQuizOption value="C">C. 一个字符串元组</BaseQuizOption>
<BaseQuizOption value="D">D. 一个字典</BaseQuizOption>
<BaseQuizAnswer><code>split()</code> 方法将一个字符串分割成一个子字符串列表。默认情况下,它按空格分割,但您可以指定不同的分隔符。</BaseQuizAnswer>
</BaseQuiz>

使用 rjust(), ljust() 和 center() 进行文本对齐

python
'Hello'.rjust(10)

output
'     Hello'

python
'Hello'.rjust(20)

output
'               Hello'

python
'Hello World'.rjust(20)

output
'         Hello World'

python
'Hello'.ljust(10)

output
'Hello     '

python
'Hello'.center(20)

output
'       Hello       '

rjust()ljust() 的可选第二个参数将指定一个除空格字符外的填充字符:

python
'Hello'.rjust(20, '*')

output
'*Hello'

python
'Hello'.ljust(20, '-')

output
'Hello---------------'

python
'Hello'.center(20, '=')

output
'=======Hello========'

使用 strip(), rstrip() 和 lstrip() 移除空格

python
spam = '    Hello World     '
spam.strip()

output
'Hello World'

python
spam.lstrip()

output
'Hello World     '

python
spam.rstrip()

output
'    Hello World'

python
spam = 'SpamSpamBaconSpamEggsSpamSpam'
spam.strip('ampS')

output
'BaconSpamEggs'

Count 方法

计算给定字符或子字符串在应用它的字符串中出现的次数。可以可选地提供起始和结束索引。

python
sentence = 'one sheep two sheep three sheep four'
sentence.count('sheep')

output
3

python
sentence.count('e')

output
9

python

返回 'one sh' 之后 e 的计数,即从字符串开头算起的第 6 个字符之后


sentence.count('e', 6)

output
8

python
sentence.count('e', 7)

output
7

Replace 方法

替换给定子字符串的所有出现,替换为另一个子字符串。可以可选地提供第三个参数来限制替换次数。返回一个新字符串。

python
text = "Hello, world!"
text.replace("world", "planet")

output
'Hello, planet!'

python
fruits = "apple, banana, cherry, apple"
fruits.replace("apple", "orange", 1)

output
'orange, banana, cherry, apple'

python
sentence = "I like apples, Apples are my favorite fruit"
sentence.replace("apples", "oranges")

output
'I like oranges, Apples are my favorite fruit'

<BaseQuiz id="cheatsheet-manipulating-strings-5" correct="C">
<template #question>
<code>replace()</code> 方法返回什么?
</template>

<BaseQuizOption value="A">A. 修改原始字符串</BaseQuizOption>
<BaseQuizOption value="B">B. 返回 <code>None</code></BaseQuizOption>
<BaseQuizOption value="C" correct>C. 返回一个已进行替换的新字符串</BaseQuizOption>
<BaseQuizOption value="D">D. 返回一个被替换字符串的列表</BaseQuizOption>
<BaseQuizAnswer><code>replace()</code> 方法返回一个新字符串,其中旧子字符串的所有出现都替换为新子字符串。原始字符串不会被修改。</BaseQuizAnswer>
</BaseQuiz>

相关链接

- <router-link to="/builtin/format">format()</router-link>
- <router-link to="/builtin/len">len()</router-link>
- <router-link to="/builtin/str">str()</router-link>
- <router-link to="/builtin/repr">repr()</router-link>
- <router-link to="/builtin/input">input()</router-link>
- <router-link to="/cheatsheet/string-formatting">字符串格式化</router-link>
- <router-link to="/cheatsheet/regular-expressions">正则表达式</router-link>

---

Cheatsheet/Zh/Oop Basics

---
title: 'Python OOP 基础 - Python 速查表'
description: '面向对象编程 (OOP) 是一种围绕对象(类实例)概念的编程范式。OOP 原则是指导软件以面向对象方式设计和开发的基本概念。在 Python 中,OOP 通过使用类和对象得到支持。以下是 Python 中一些基本的 OOP 原则'
labUrl: 'https://labex.io/zh/labs/python-python-oop-basics-633662?course=python-cheatsheet'
---

<base-title :title="frontmatter.title" :description="frontmatter.description">
Python OOP 基础
</base-title>

<base-lab-url :url="frontmatter.labUrl" />

<base-disclaimer>
<base-disclaimer-title>
<a href="https://en.wikipedia.org/wiki/Object-oriented_programming">面向对象编程</a>
</base-disclaimer-title>
<base-disclaimer-content>
面向对象编程(OOP)是一种基于“对象”概念的编程范例,对象可以包含数据和代码。数据以字段(通常称为属性或特性)的形式存在,代码以过程(通常称为方法)的形式存在。
</base-disclaimer-content>
</base-disclaimer>

封装 (Encapsulation)

封装是面向对象编程的基本概念之一,它有助于保护对象的数据方法免受未经授权的访问和修改。这是一种实现数据抽象的方式,意味着对象的实现细节对外部世界是隐藏的,只暴露必要的信息。

在 Python 中,可以通过使用访问修饰符来实现封装。访问修饰符是定义类中属性和方法可访问性的关键字。Python 中可用的三种访问修饰符是 public(公有)、private(私有)和 protected(保护)。然而,Python 没有像 Java 和 C++ 等其他编程语言那样明确定义访问修饰符的方式。相反,它使用下划线前缀的约定来指示访问级别。

在给定的代码示例中,MyClass 类有两个属性,_protected_var__private_var_protected_var 使用单个下划线前缀标记为受保护。这意味着该属性可以在类及其子类中访问,但不能在类外部访问。__private_var 使用双下划线前缀标记为私有。这意味着该属性只能在类内部访问,不能在类外部访问,甚至不能在子类中访问。

当我们创建 MyClass 类的一个对象时,我们可以使用带有单个下划线前缀的对象名称来访问 _protected_var 属性。但是,我们不能使用对象名称访问 __private_var 属性,因为它对外部世界是隐藏的。如果我们尝试访问 __private_var 属性,我们将得到一个 AttributeError,如代码所示。

总之,封装是面向对象编程中的一个重要概念,有助于保护对象的实现细节。在 Python 中,我们可以通过使用访问修饰符和使用下划线前缀来指示访问级别来实现封装。

python

定义一个名为 MyClass 的类


class MyClass:

# 构造函数,用于初始化类对象
def __init__(self):

# 定义一个初始值为 10 的受保护变量
# 变量名以单个下划线开头,表示受保护的访问
self._protected_var = 10

# 定义一个初始值为 20 的私有变量
# 变量名以双下划线开头,表示私有的访问
self.__private_var = 20

创建 MyClass 类的一个对象


obj = MyClass()

使用对象名称和单个下划线前缀访问受保护的变量并打印其值


受保护的变量可以在类外部访问,但


旨在在类或其子类中使用


print(obj._protected_var) # 输出:10

尝试使用对象名称访问私有变量并打印其值


私有变量不能在类外部访问,即使是子类也不能


这将引发一个 AttributeError,因为该变量在类外部不可访问


print(obj.__private_var) # AttributeError: 'MyClass' object has no attribute '__private_var'

<BaseQuiz id="cheatsheet-oop-basics-1" correct="B">
<template #question>
如何在 Python 中指示一个受保护的变量?
</template>

<BaseQuizOption value="A">A. 双下划线前缀:<code>variable</code></BaseQuizOption>
<BaseQuizOption value="B" correct>B. 单下划线前缀:<code>_variable</code></BaseQuizOption>
<BaseQuizOption value="C">C. 不需要下划线</BaseQuizOption>
<BaseQuizOption value="D">D. 三下划线前缀:<code>_variable</code></BaseQuizOption>
<BaseQuizAnswer>在 Python 中,单个下划线前缀 (<code>\_variable</code>) 表示一个受保护的变量,这是一种约定,意味着它应该在类或其子类中使用。双下划线 (<code>\_\_variable</code>) 表示一个私有变量。</BaseQuizAnswer>
</BaseQuiz>

继承 (Inheritance)

继承促进了代码重用,并允许您创建共享通用属性和方法的类层次结构。它通过将相关功能保持在一个地方并促进模块化概念,有助于创建干净、有组织的 कोड。从中派生新类的基类也称为父类,新类称为子类或派生类。

在代码中,我们定义了一个名为 Animal 的类,它有一个构造函数方法,用于用 name 属性初始化类对象,以及一个名为 speak 的方法。speak 方法定义在 Animal 类中,但没有主体。

然后我们定义了两个名为 DogCat 的子类,它们都继承自 Animal 类。这些子类覆盖了 Animal 类的 speak 方法。

我们创建了一个 name 属性为 "Rover" 的 Dog 对象和一个 name 属性为 "Whiskers" 的 Cat 对象。我们使用 dog.speak() 调用 Dog 对象的 speak 方法,它打印 "Woof!",因为 Dog 类的 speak 方法覆盖了 Animal 类的 speak 方法。类似地,我们使用 cat.speak() 调用 Cat 对象的 speak 方法,它打印 "Meow!",因为 Cat 类的 speak 方法覆盖了 Animal 类的 speak 方法。

python

定义一个名为 Animal 的类


class Animal:

# 构造函数,用于用 name 属性初始化类对象
def __init__(self, name):
self.name = name

# 在 Animal 类中定义但没有主体的类方法
# 此方法将被 Animal 的子类覆盖
def speak(self):
print("")

定义一个继承自 Animal 类的名为 Dog 的子类


class Dog(Animal):

# 覆盖 Animal 类的 speak 方法
def speak(self):
print("Woof!")

定义一个继承自 Animal 类的名为 Cat 的子类


class Cat(Animal):

# 覆盖 Animal 类的 speak 方法
def speak(self):
print("Meow!")

创建一个 name 属性为 "Rover" 的 Dog 对象


dog = Dog("Rover")

创建一个 name 属性为 "Whiskers" 的 Cat 对象


cat = Cat("Whiskers")

调用 Dog 类的 speak 方法并打印输出


Dog 类的 speak 方法覆盖了 Animal 类的 speak 方法


因此,当我们调用 Dog 对象的 speak 方法时,它将打印 "Woof!"


dog.speak() # 输出:Woof!

调用 Cat 类的 speak 方法并打印输出


Cat 类的 speak 方法覆盖了 Animal 类的 speak 方法


因此,当我们调用 Cat 对象的 speak 方法时,它将打印 "Meow!"


cat.speak() # 输出:Meow!

<BaseQuiz id="cheatsheet-oop-basics-2" correct="A">
<template #question>
Python 中的继承是什么?
</template>

<BaseQuizOption value="A" correct>A. 一个类可以从另一个类继承属性和方法的机制</BaseQuizOption>
<BaseQuizOption value="B">B. 复制对象的方式</BaseQuizOption>
<BaseQuizOption value="C">C. 删除类的方法</BaseQuizOption>
<BaseQuizOption value="D">D. 一个内置函数</BaseQuizOption>
<BaseQuizAnswer>继承允许一个类(子类/派生类)从另一个类(父类/基类)继承属性和方法。这促进了代码重用,并允许您创建类层次结构。</BaseQuizAnswer>
</BaseQuiz>

多态性 (Polymorphism)

多态性是面向对象编程中的一个重要概念,它允许您以统一的方式处理不同类的对象。在 Python 中,多态性是通过使用方法覆盖或方法重载来实现的。

方法覆盖是指子类提供对父类中已定义方法的自己实现。这允许子类在不更改方法名称或签名的情况下修改方法的行为。

方法重载是指多个方法具有相同的名称但参数不同。Python 不直接支持方法重载,但可以通过使用默认参数或可变长度参数来实现。

多态性使编写灵活且可重用的代码变得更容易。它允许您编写可以处理不同对象而无需知道其特定类型的代码。

python

Shape 类被定义了一个抽象的 area 方法,旨在被子类覆盖。


class Shape:
def area(self):
pass

class Rectangle(Shape):
# Rectangle 类被定义了一个 __init__ 方法,用于初始化
# width 和 height 实例变量。
# 它还定义了一个 area 方法,使用 width 和 height 实例变量计算并返回
# 矩形的面积。
def __init__(self, width, height):
self.width = width # 初始化 width 实例变量
self.height = height # 初始化 height 实例变量

def area(self):
return self.width * self.height # 返回矩形的面积


# Circle 类被定义了一个 __init__ 方法
# 用于初始化一个 radius 实例变量。
# 它还定义了一个 area 方法,使用 radius 实例变量计算并
# 返回圆的面积。
class Circle(Shape):
def __init__(self, radius):
self.radius = radius # 初始化 radius 实例变量

def area(self):
return 3.14 self.radius 2 # 使用 pi r^2 返回圆的面积

shapes 列表被创建,包含一个 Rectangle 对象和一个 Circle 对象。for


循环遍历列表中的每个对象并调用每个对象的 area 方法。


输出将是矩形的面积 (20) 和圆的面积 (153.86)。


shapes = [Rectangle(4, 5), Circle(7)] # 创建一个 Shape 对象列表
for shape in shapes:
print(shape.area()) # 输出每个 Shape 对象的面积

<BaseQuiz id="cheatsheet-oop-basics-3" correct="C">
<template #question>
Python 中的多态性是什么?
</template>

<BaseQuizOption value="A">A. 创建多个同名类</BaseQuizOption>
<BaseQuizOption value="B">B. 隐藏实现细节</BaseQuizOption>
<BaseQuizOption value="C" correct>C. 能够通过通用接口以统一的方式使用不同类的对象</BaseQuizOption>
<BaseQuizOption value="D">D. 复制对象</BaseQuizOption>
<BaseQuizAnswer>多态性允许您以统一的方式处理不同类的对象。不同的类可以实现相同的方法名称,Python 会根据对象的类型调用适当的实现。</BaseQuizAnswer>
</BaseQuiz>

抽象 (Abstraction)

抽象是面向对象编程(OOP)中的一个重要概念,因为它允许您关注对象的基本特征或系统的基本特征,而忽略与当前上下文不相关的细节。通过减少复杂性和隐藏不必要的细节,抽象可以使代码更具模块化、更易于阅读和更容易维护。

在 Python 中,可以通过使用抽象类或接口来实现抽象。抽象类不能直接实例化,而是旨在被其他类继承。它通常包含没有实现的抽象方法,但为子类应如何实现提供了一个模板。这允许程序员为一组相关的类定义一个通用接口,同时仍然允许每个类具有自己特定的行为。

另一方面,接口是一组方法签名,类必须实现这些签名才能被认为与该接口“兼容”。接口通常用于定义多个类可以实现的一组通用方法,允许它们在某些情况下可以互换使用。

Python 没有对抽象类或接口的内置支持,但可以使用 abc(抽象基类)模块来实现它们。该模块提供了 ABC 类和 abstractmethod 装饰器,可用于定义抽象类和方法。

总而言之,抽象是管理复杂性和提高面向对象编程中代码质量的有力工具,Python 提供了多种选项来实现代码中的抽象。

python

从 abc 模块导入以定义抽象类和方法


from abc import ABC, abstractmethod

定义一个名为 Shape 的抽象类,它有一个名为 area 的抽象方法


class Shape(ABC):
@abstractmethod
def area(self):
pass

定义一个继承自 Shape 的 Rectangle 类


class Rectangle(Shape):
def __init__(self, width, height):
self.width = width
self.height = height

# 为矩形实现 area 方法
def area(self):
return self.width * self.height

定义一个也继承自 Shape 的 Circle 类


class Circle(Shape):
def __init__(self, radius):
self.radius = radius

# 为圆形实现 area 方法
def area(self):
return 3.14 self.radius * 2

创建一个包含 Rectangle 和 Circle 对象的形状列表


shapes = [Rectangle(4, 5), Circle(7)]

遍历列表中的每个形状并打印其面积


for shape in shapes:
print(shape.area())

这些是 Python 中的一些基本 OOP 原则。此页面仍在完善中,更多详细示例和解释即将推出。

相关链接

- <router-link to="/cheatsheet/functions">函数 (Functions)</router-link>
- <router-link to="/cheatsheet/decorators">装饰器 (Decorators)</router-link>
- <router-link to="/cheatsheet/exception-handling">异常处理 (Exception Handling)</router-link>
- <router-link to="/cheatsheet/dataclasses">数据类 (Dataclasses)</router-link>
- <router-link to="/builtin/object">object()</router-link>
- <router-link to="/builtin/classmethod">classmethod()</router-link>
- <router-link to="/builtin/staticmethod">staticmethod()</router-link>
- <router-link to="/builtin/property">property()</router-link>
- <router-link to="/builtin/isinstance">isinstance()</router-link>
- <router-link to="/builtin/issubclass">issubclass()</router-link>
- <router-link to="/builtin/super">super()</router-link>

---

Cheatsheet/Zh/Packaging

---
title: 'Python 打包 - Python 速查表'
description: '学习如何使用 setup.py 和 pyproject.toml 打包 Python 项目。了解基于 PEP-517、PEP-518 和 PEP-660 规范的现代 Python 打包方法。'
labUrl: 'https://labex.io/zh/labs/python-python-setup-py-633666?course=python-cheatsheet'
---

<base-title :title="frontmatter.title" :description="frontmatter.description">
Python 打包
</base-title>

<base-lab-url :url="frontmatter.labUrl" />

<base-warning>
<base-warning-title>
一个“有争议的”观点
</base-warning-title>
<base-warning-content>
使用 <code>setup.py</code> 来打包和分发你的 Python 包有时会非常具有挑战性。像 <a target="_blank" href="https://python-poetry.org/">Poetry</a> 和 <a target="_blank" href="https://docs.astral.sh/uv/">UV</a> 这样的现代工具不仅使打包容易得多,而且还能以非常方便的方式帮助你管理依赖项。UV 特别值得注意,因为它比传统工具快 10-100 倍。
</base-warning-content>
</base-warning>

如果你想了解更多关于 Poetry 的信息,可以阅读以下文章:

- <router-link to="/blog/python-projects-with-poetry-and-vscode-part-1">使用 Poetry 和 VSCode 的 Python 项目。第 1 部分</router-link>
- <router-link to="/blog/python-projects-with-poetry-and-vscode-part-2">使用 Poetry 和 VSCode 的 Python 项目。第 2 部分</router-link>
- <router-link to="/blog/python-projects-with-poetry-and-vscode-part-3">使用 Poetry 和 VSCode 的 Python 项目。第 3 部分</router-link>

有关闪电般快速的 Python 包管理器 UV 的全面指南,请阅读:<router-link to="/blog/python-uv-package-manager">UV:闪电般的 Python 包管理器</router-link>。

简介

Python 打包是准备你的 Python 项目以供分发和安装的过程。主要有两种方法:传统的 <code>setup.py</code> 方法和现代的 <code>pyproject.toml</code> 方法(定义在 PEP-517、PEP-518 和 PEP-660 中)。

有关处理文件和目录路径的全面指南(这对管理项目结构至关重要),请参阅 <router-link to="/cheatsheet/file-directory-path">文件和目录路径</router-link> 页面。

传统方法:setup.py

<code>setup.py</code> 文件是传统 Python 项目的核心。它描述了关于你项目的所有元数据。你可以向项目添加相当多的字段,以提供描述该项目的丰富元数据。然而,只有三个字段是必需的:<code>name</code>、<code>version</code> 和 <code>packages</code>。如果希望将包发布到 Python 包索引 (PyPI),<code>name</code> 字段必须是唯一的。<code>version</code> 字段用于跟踪项目的不同版本。<code>packages</code> 字段描述了你在项目中放置 Python 源代码的位置。

这使得你可以轻松安装 Python 包。通常,编写以下内容就足够了:

bash
python setup.py install

然后模块将自行安装。

示例:setup.py

我们最初的 setup.py 还会包含有关许可证的信息,并将重用 README.txt 文件作为 long_description 字段。它看起来像这样:

python

setup.py: define package metadata for distribution


from distutils.core import setup
setup(
name='pythonCheatsheet', # Package name (must be unique on PyPI)
version='0.1', # Version number
packages=['pipenv',], # List of packages to include
license='MIT', # License type
long_description=open('README.txt').read(), # Read description from file
)

<BaseQuiz id="cheatsheet-packaging-1" correct="C">
<template #question>
<code>setup.py</code> 文件中三个必需的字段是什么?
</template>

<BaseQuizOption value="A">A. name, author, license</BaseQuizOption>
<BaseQuizOption value="B">B. name, description, packages</BaseQuizOption>
<BaseQuizOption value="C" correct>C. name, version, packages</BaseQuizOption>
<BaseQuizOption value="D">D. name, version, license</BaseQuizOption>
<BaseQuizAnswer><code>setup.py</code> 中的三个必需字段是 <code>name</code>(包名,在 PyPI 上必须唯一)、<code>version</code>(跟踪版本)和 <code>packages</code>(描述 Python 源代码所在位置)。</BaseQuizAnswer>
</BaseQuiz>

现代方法:pyproject.toml

<code>pyproject.toml</code> 文件是 Python 项目配置的现代标准(PEP-517、PEP-518、PEP-660)。它提供了一种统一的方式,在一个声明性的单一文件中指定构建系统要求和项目元数据。

pyproject.toml 的优势

- 声明式 (Declarative):所有项目元数据集中在一个地方
- 构建系统无关 (Build system agnostic):可与 setuptools、poetry、flit 和其他构建后端配合使用
- 无代码执行 (No code execution):比 setup.py 更安全、更可预测
- 标准化 (Standardized):遵循 PEP 标准,以获得更好的工具支持

示例:pyproject.toml

这是一个使用 setuptools 的基本 <code>pyproject.toml</code> 示例:

toml
[build-system]
requires = ["setuptools>=61.0", "wheel"]
build-backend = "setuptools.build_meta"

[project]
name = "pythonCheatsheet"
version = "0.1"
description = "A Python cheatsheet package"
readme = "README.txt"
requires-python = ">=3.8"
license = {text = "MIT"}
authors = [
{name = "Your Name", email = "[email protected]"}
]
classifiers = [
"Programming Language :: Python :: 3",
"License :: OSI Approved :: MIT License",
]

[project.optional-dependencies]
dev = [
"pytest>=7.0",
"black>=22.0",
]

从 pyproject.toml 安装

使用 <code>pyproject.toml</code>,你可以使用 pip 安装你的包:

bash
pip install .

或者以可编辑模式:

bash
pip install -e .

<BaseQuiz id="cheatsheet-packaging-2" correct="B">
<template #question>
<code>pyproject.toml</code> 相对于 <code>setup.py</code> 的主要优势是什么?
</template>

<BaseQuizOption value="A">A. 执行速度更快</BaseQuizOption>
<BaseQuizOption value="B" correct>B. 它是声明式的、更安全(无代码执行)并遵循 PEP 标准</BaseQuizOption>
<BaseQuizOption value="C">C. 它需要的配置更少</BaseQuizOption>
<BaseQuizOption value="D">D. 它只适用于 Python 3.10+</BaseQuizOption>
<BaseQuizAnswer><code>pyproject.toml</code> 方法是声明式的(所有元数据集中在一个地方),比执行代码的 <code>setup.py</code> 更安全,并且遵循 PEP 标准(PEP-517、PEP-518、PEP-660)以获得更好的工具支持。</BaseQuizAnswer>
</BaseQuiz>

选择正确的方法

- 使用 <code>setup.py</code>:如果你正在处理遗留项目或需要细粒度的控制
- 使用 <code>pyproject.toml</code>:用于新项目(推荐),因为它代表现代标准并提供更好的工具支持

访问官方文档了解更多信息。

相关链接

- <router-link to="/cheatsheet/virtual-environments">虚拟环境</router-link>
- <router-link to="/cheatsheet/file-directory-path">文件和目录路径</router-link>
- <router-link to="/blog/python-uv-package-manager">UV:闪电般的 Python 包管理器</router-link>
- <router-link to="/blog/python-projects-with-poetry-and-vscode-part-1">使用 Poetry 和 VSCode 的 Python 项目。第 1 部分</router-link>
- <router-link to="/blog/python-projects-with-poetry-and-vscode-part-2">使用 Poetry 和 VSCode 的 Python 项目。第 2 部分</router-link>
- <router-link to="/blog/python-projects-with-poetry-and-vscode-part-3">使用 Poetry 和 VSCode 的 Python 项目。第 3 部分</router-link>
- <router-link to="/builtin/import">import()</router-link>

---

Cheatsheet/Zh/Reading And Writing Files

---
title: 'Python 文件读写速查表'
description: '在 Python 中读写文件,推荐使用 with 语句,它能自动管理资源并确保文件在使用后被关闭。'
labUrl: 'https://labex.io/zh/labs/python-python-reading-and-writing-files-633663?course=python-cheatsheet'
---

<base-title :title="frontmatter.title" :description="frontmatter.description">
文件读写
</base-title>

<base-lab-url :url="frontmatter.labUrl" />

有关文件和目录路径操作的更深入了解,请参阅 <router-link to="/cheatsheet/file-directory-path">文件和目录路径</router-link> 页面。

文件读写过程

要在 Python 中读/写文件,您应该使用 with 语句,它会在您完成后自动关闭文件,为您管理可用资源。

打开和读取文件

open 函数打开一个文件并返回一个相应的文件对象。

python

使用 'with' 语句读取文件:完成后自动关闭文件


with open('/home/labex/project/hi.txt') as hello_file:
hello_content = hello_file.read() # 读取整个文件内容

hello_content

output
'Hello World!'

<BaseQuiz id="cheatsheet-reading-and-writing-files-1" correct="A">
<template #question>
使用 <code>with</code> 语句打开文件的主要优点是什么?
</template>

<BaseQuizOption value="A" correct>A. 完成后文件会自动关闭,即使发生错误</BaseQuizOption>
<BaseQuizOption value="B">B. 文件打开速度更快</BaseQuizOption>
<BaseQuizOption value="C">C. 文件可以同时以读写模式打开</BaseQuizOption>
<BaseQuizOption value="D">D. 文件会自动压缩</BaseQuizOption>
<BaseQuizAnswer><code>with</code> 语句确保在退出代码块时文件会自动关闭,即使发生异常也是如此。这有助于正确管理资源。</BaseQuizAnswer>
</BaseQuiz>

或者,您可以使用 _readlines()_ 方法从文件中获取字符串值列表,文件中的每一行对应一个字符串:

python

readlines() 方法:返回字符串列表,每行一个字符串


with open('sonnet29.txt') as sonnet_file:
sonnet_file.readlines() # 返回一个列表,其中每行都是一个字符串

output
['When, in disgrace with fortune and men's eyes,\n',
' I all alone beweep my outcast state,\n',
"And trouble deaf heaven with my bootless cries,\n",
"And look upon myself and curse my fate,']

您也可以逐行迭代文件:

python

逐行迭代文件(对大文件更节省内存)


with open('sonnet29.txt') as sonnet_file:
for line in sonnet_file: # 文件对象是可迭代的
print(line, end='') # 打印时不加额外换行

output
When, in disgrace with fortune and men's eyes,
I all alone beweep my outcast state,
And trouble deaf heaven with my bootless cries,
And look upon myself and curse my fate,

写入文件

python

写入文件:'w' 模式会覆盖现有文件


with open('bacon.txt', 'w') as bacon_file: # 'w' = 写入模式
bacon_file.write('Hello world!\n') # 返回写入的字符数

output
13

python

追加到文件:'a' 模式会追加到现有文件


with open('bacon.txt', 'a') as bacon_file: # 'a' = 追加模式
bacon_file.write('Bacon is not a vegetable.')

output
25

python
with open('bacon.txt') as bacon_file:
content = bacon_file.read()

print(content)

output
Hello world!
Bacon is not a vegetable.

<BaseQuiz id="cheatsheet-reading-and-writing-files-2" correct="B">
<template #question>
打开文件时,模式 <code>'w'</code> 和模式 <code>'a'</code> 有什么区别?
</template>

<BaseQuizOption value="A">A. <code>'w'</code> 用于读取,<code>'a'</code> 用于写入</BaseQuizOption>
<BaseQuizOption value="B" correct>B. <code>'w'</code> 覆盖文件,<code>'a'</code> 追加到文件</BaseQuizOption>
<BaseQuizOption value="C">C. <code>'w'</code> 用于 Windows,<code>'a'</code> 用于 Apple</BaseQuizOption>
<BaseQuizOption value="D">D. 没有区别</BaseQuizOption>
<BaseQuizAnswer>模式 <code>'w'</code> 以写入方式打开文件并覆盖任何现有内容。模式 <code>'a'</code> 以追加方式打开文件,将新内容添加到文件末尾。</BaseQuizAnswer>
</BaseQuiz>

相关链接

- <router-link to="/cheatsheet/file-directory-path">文件和目录路径</router-link>
- <router-link to="/cheatsheet/json-yaml">JSON 和 YAML</router-link>
- <router-link to="/blog/python-pathlib-essentials">每位开发者都应知道的 10 个基本文件系统操作</router-link>
- <router-link to="/builtin/open">open()</router-link>
- <router-link to="/builtin/print">print()</router-link>

---

Cheatsheet/Zh/Regular Expressions

---
title: 'Python 正则表达式 - Python 速查表'
description: '正则表达式(Regex)是一串字符序列,用于在文本中指定搜索模式,并被字符串搜索算法使用。'
labUrl: 'https://labex.io/zh/labs/python-python-regular-expressions-633664?course=python-cheatsheet'
---

<base-title :title="frontmatter.title" :description="frontmatter.description">
正则表达式
</base-title>

<base-lab-url :url="frontmatter.labUrl" />

<base-disclaimer>
<base-disclaimer-title>
<a target="_blank" href="https://en.wikipedia.org/wiki/Regular_expression">正则表达式</a>
</base-disclaimer-title>
<base-disclaimer-content>
正则表达式(缩写为 regex [...])是一系列字符,用于在文本中指定搜索模式。[...] 用于字符串搜索算法,对字符串执行“查找”或“查找和替换”操作,或用于输入验证。
</base-disclaimer-content>
</base-disclaimer>

1. 使用 import re 导入 regex 模块。
2. 使用 re.compile() 函数创建 Regex 对象。(记住使用原始字符串。)
3. 将要搜索的字符串传递给 Regex 对象的 search() 方法。这将返回一个 Match 对象。
4. 调用 Match 对象的 group() 方法以返回实际匹配文本的字符串。

Python 中所有的 regex 函数都在 re 模块中:

python

Import re module for regular expression operations


import re

Regex 符号

| 符号 | 匹配内容 |
| :----------------------- | :----------------------------------------- |
| ? | 前一个组的零个或一个。 |
| * | 前一个组的零个或多个。 |
| + | 前一个组的一个或多个。 |
| {n} | 前一个组的正好 n 个。 |
| {n,} | 前一个组的 n 个或更多。 |
| {,m} | 前一个组的 0 到 m 个。 |
| {n,m} | 前一个组的至少 n 个且至多 m 个。 |
| {n,m}?*?+? | 对前一个组执行非贪婪匹配。 |
| ^spam | 意味着字符串必须以 spam 开头。 |
| spam$ | 意味着字符串必须以 spam 结尾。 |
| . | 任何字符,换行符除外。 |
| \d, \w, 和 \s | 分别表示数字、单词或空格字符。 |
| \D, \W, 和 \S | 分别表示非数字、非单词或非空格的任何字符。 |
| [abc] | 方括号之间的任何字符(如 a、b、 )。 |
| [^abc] | 方括号之间以外的任何字符。 |

匹配 regex 对象

python

re.compile(): create regex pattern object (use raw string r'' to avoid escaping)


phone_num_regex = re.compile(r'\d\d\d-\d\d\d-\d\d\d\d') # Pattern: 3 digits-3 digits-4 digits

mo = phone_num_regex.search('My number is 415-555-4242.') # Search for pattern

print(f'Phone number found: {mo.group()}') # group() returns matched text

output
Phone number found: 415-555-4242

使用圆括号进行分组

python

Parentheses create groups: group(1) returns first group, group(2) returns second


phone_num_regex = re.compile(r'(\d\d\d)-(\d\d\d-\d\d\d\d)') # Two groups in parentheses
mo = phone_num_regex.search('My number is 415-555-4242.')

mo.group(1) # Returns first group: '415'

output
'415'

python
mo.group(2)

output
'555-4242'

python
mo.group(0)

output
'415-555-4242'

python
mo.group()

output
'415-555-4242'

<BaseQuiz id="cheatsheet-regular-expressions-1" correct="A">
<template #question>
当在匹配对象上调用 <code>group()</code> 时,它返回什么?
</template>

<BaseQuizOption value="A" correct>A. 整个匹配的文本</BaseQuizOption>
<BaseQuizOption value="B">B. 仅第一个组</BaseQuizOption>
<BaseQuizOption value="C">C. 所有组作为一个列表</BaseQuizOption>
<BaseQuizOption value="D">D. 匹配的索引</BaseQuizOption>
<BaseQuizAnswer><code>group()</code> 方法(或 <code>group(0)</code>)返回整个匹配的文本。要获取特定组,请使用 <code>group(1)</code>、<code>group(2)</code> 等。</BaseQuizAnswer>
</BaseQuiz>

要一次性检索所有组,请使用 groups() 方法:

python

groups(): returns tuple of all groups


mo.groups() # Returns ('415', '555-4242')

output
('415', '555-4242')

python
area_code, main_number = mo.groups()

print(area_code)

output
415

python
print(main_number)

output
555-4242

使用管道进行多重分组

您可以在任何想要匹配多个表达式中的一个的地方使用 | 字符。

python
hero_regex = re.compile (r'Batman|Tina Fey')

mo1 = hero_regex.search('Batman and Tina Fey.')
mo1.group()

output
'Batman'

python
mo2 = hero_regex.search('Tina Fey and Batman.')
mo2.group()

output
'Tina Fey'

您也可以在正则表达式中使用管道来匹配多个模式中的一个:

python
bat_regex = re.compile(r'Bat(man|mobile|copter|bat)')
mo = bat_regex.search('Batmobile lost a wheel')

mo.group()

output
'Batmobile'

python
mo.group(1)

output
'mobile'

使用问号进行可选匹配

? 字符将它前面的组标记为模式的可选部分。

python
bat_regex = re.compile(r'Bat(wo)?man')

mo1 = bat_regex.search('The Adventures of Batman')
mo1.group()

output
'Batman'

python
mo2 = bat_regex.search('The Adventures of Batwoman')
mo2.group()

output
'Batwoman'

使用星号匹配零个或多个

*(星号)表示“匹配零个或多个”。位于星号之前的组可以在文本中出现任意次数。

python
bat_regex = re.compile(r'Bat(wo)*man')
mo1 = bat_regex.search('The Adventures of Batman')
mo1.group()

output
'Batman'

python
mo2 = bat_regex.search('The Adventures of Batwoman')
mo2.group()

output
'Batwoman'

python
mo3 = bat_regex.search('The Adventures of Batwowowowoman')
mo3.group()

output
'Batwowowowoman'

使用加号匹配一个或多个

+(加号)表示匹配一个或多个。加号前面的组必须至少出现一次:

python
bat_regex = re.compile(r'Bat(wo)+man')

mo1 = bat_regex.search('The Adventures of Batwoman')
mo1.group()

output
'Batwoman'

python
mo2 = bat_regex.search('The Adventures of Batwowowowoman')
mo2.group()

output
'Batwowowowoman'

python
mo3 = bat_regex.search('The Adventures of Batman')
mo3 is None

output
True

使用花括号匹配特定重复次数

如果你有一个你想重复特定次数的组,在你的正则表达式中跟在组后面加上花括号中的数字:

python
ha_regex = re.compile(r'(Ha){3}')

mo1 = ha_regex.search('HaHaHa')
mo1.group()

output
'HaHaHa'

python
mo2 = ha_regex.search('Ha')
mo2 is None

output
True

你可以用花括号之间的最小和最大值来指定一个范围,而不是一个数字。例如,正则表达式 (Ha){3,5} 将匹配 'HaHaHa'、'HaHaHaHa' 和 'HaHaHaHaHa'。

python
ha_regex = re.compile(r'(Ha){2,3}')
mo1 = ha_regex.search('HaHaHaHa')
mo1.group()

output
'HaHaHa'

贪婪匹配和非贪婪匹配

Python 的正则表达式默认是贪婪的:在有歧义的情况下,它们会匹配尽可能长的字符串。花括号的非贪婪版本(匹配最短字符串)在闭合花括号后跟一个问号。

python
greedy_ha_regex = re.compile(r'(Ha){3,5}')

mo1 = greedy_ha_regex.search('HaHaHaHaHa')
mo1.group()

output
'HaHaHaHaHa'

python
non_greedy_ha_regex = re.compile(r'(Ha){3,5}?')
mo2 = non_greedy_ha_regex.search('HaHaHaHaHa')
mo2.group()

output
'HaHaHa'

<BaseQuiz id="cheatsheet-regular-expressions-2" correct="B">
<template #question>
什么使得正则表达式模式成为非贪婪的?
</template>

<BaseQuizOption value="A">A. 使用 <code>_</code> 而不是 <code>+</code></BaseQuizOption>
<BaseQuizOption value="B" correct>B. 在量词后添加一个 <code>?</code> (例如 <code>_?</code>, <code>+?</code>, <code>{3,5}?</code>)</BaseQuizOption>
<BaseQuizOption value="C">C. 使用圆括号</BaseQuizOption>
<BaseQuizOption value="D">D. 使用方括号</BaseQuizOption>
<BaseQuizAnswer>在 <code>\*</code>、<code>+</code> 或 <code>{n,m}</code> 等量词后添加 <code>?</code> 会使其成为非贪婪的,匹配最短的可能字符串而不是最长的。</BaseQuizAnswer>
</BaseQuiz>

findall() 方法

findall() 方法将返回搜索字符串中所有匹配项的字符串列表。

python
phone_num_regex = re.compile(r'\d\d\d-\d\d\d-\d\d\d\d') # has no groups

phone_num_regex.findall('Cell: 415-555-9999 Work: 212-555-0000')

output
['415-555-9999', '212-555-0000']

创建自定义字符类

您可以使用方括号定义自己的字符类。例如,字符类 _[aeiouAEIOU]_ 将匹配任何元音字母,包括大小写。

python
vowel_regex = re.compile(r'[aeiouAEIOU]')
vowel_regex.findall('Robocop eats baby food. BABY FOOD.')

output
['o', 'o', 'o', 'e', 'a', 'a', 'o', 'o', 'A', 'O', 'O']

您也可以通过使用连字符包含字母或数字的范围。例如,字符类 _[a-zA-Z0-9]_ 将匹配所有小写字母、大写字母和数字。

通过在字符类的开方括号后放置一个脱字符号 (^),您可以创建一个负字符类,它将匹配字符类中不包含的所有字符:

python
consonant_regex = re.compile(r'[^aeiouAEIOU]')
consonant_regex.findall('Robocop eats baby food. BABY FOOD.')

output
['R', 'b', 'c', 'p', ' ', 't', 's', ' ', 'b', 'b', 'y', ' ', 'f', 'd', '.', ' ', 'B', 'B', 'Y', ' ', 'F', 'D', '.']

脱字符号和美元符号字符

- 您也可以在正则表达式的开头使用脱字符号 ^ 来指示匹配必须发生在搜索文本的开头。

- 同样,您可以在正则表达式的末尾放置一个美元符号 $ 来指示字符串必须以该正则表达式模式结尾。

- 您可以同时使用 ^$ 来指示整个字符串必须匹配该正则表达式。

正则表达式字符串 r'^Hello' 匹配以 'Hello' 开头的字符串:

python
begins_with_hello = re.compile(r'^Hello')
begins_with_hello.search('Hello world!')

output
<_sre.SRE_Match object; span=(0, 5), match='Hello'>

python
begins_with_hello.search('He said hello.') is None

output
True

正则表达式字符串 r'\d\$' 匹配以 0 到 9 的数字字符结尾的字符串:

python
whole_string_is_num = re.compile(r'^\d+$')

whole_string_is_num.search('1234567890')

output
<_sre.SRE_Match object; span=(0, 10), match='1234567890'>

python
whole_string_is_num.search('12345xyz67890') is None

output
True

python
whole_string_is_num.search('12 34567890') is None

output
True

通配符字符

正则表达式中的 .(点)字符将匹配除换行符外的任何字符:

python
at_regex = re.compile(r'.at')

at_regex.findall('The cat in the hat sat on the flat mat.')

output
['cat', 'hat', 'sat', 'lat', 'mat']

使用点星号匹配所有内容

python
name_regex = re.compile(r'First Name: (.) Last Name: (.)')

mo = name_regex.search('First Name: Al Last Name: Sweigart')
mo.group(1)

output
'Al'

python
mo.group(2)

output
'Sweigart'

. 默认使用贪婪模式:它总是会尝试匹配尽可能多的文本。要以非贪婪方式匹配任何和所有文本,请使用点、星号和问号 (.?)。问号告诉 Python 以非贪婪方式匹配:

python
non_greedy_regex = re.compile(r'<.*?>')
mo = non_greedy_regex.search('<To serve man> for dinner.>')
mo.group()

output
'<To serve man>'

python
greedy_regex = re.compile(r'<.*>')
mo = greedy_regex.search('<To serve man> for dinner.>')
mo.group()

output
'<To serve man> for dinner.>'

使用点字符匹配换行符

点星号会匹配除换行符外的所有内容。通过将 re.DOTALL 作为第二个参数传递给 re.compile(),您可以使点字符匹配所有字符,包括换行符:

python
no_newline_regex = re.compile('.*')
no_newline_regex.search('Serve the public trust.\nProtect the innocent.\nUphold the law.').group()

output
'Serve the public trust.'

python
newline_regex = re.compile('.*', re.DOTALL)
newline_regex.search('Serve the public trust.\nProtect the innocent.\nUphold the law.').group()

output
'Serve the public trust.\nProtect the innocent.\nUphold the law.'

忽略大小写匹配

要使正则表达式忽略大小写,您可以将 re.IGNORECASEre.I 作为第二个参数传递给 re.compile()

python
robocop = re.compile(r'robocop', re.I)

robocop.search('Robocop is part man, part machine, all cop.').group()

output
'Robocop'

python
robocop.search('ROBOCOP protects the innocent.').group()

output
'ROBOCOP'

python
robocop.search('Al, why does your programming book talk about robocop so much?').group()

output
'robocop'

使用 sub() 方法替换字符串

Regex 对象的 sub() 方法接收两个参数:

1. 第一个参数是要替换任何匹配项的字符串。
2. 第二个参数是正则表达式的字符串。

sub() 方法返回一个已应用替换的字符串:

python
names_regex = re.compile(r'Agent \w+')

names_regex.sub('CENSORED', 'Agent Alice gave the secret documents to Agent Bob.')

output
'CENSORED gave the secret documents to CENSORED.'

<BaseQuiz id="cheatsheet-regular-expressions-3" correct="B">
<template #question>
<code>sub()</code> 方法的作用是什么?
</template>

<BaseQuizOption value="A">A. 查找字符串中的所有匹配项</BaseQuizOption>
<BaseQuizOption value="B" correct>B. 用替换字符串替换所有匹配项</BaseQuizOption>
<BaseQuizOption value="C">C. 在匹配处分割字符串</BaseQuizOption>
<BaseQuizOption value="D">D. 验证字符串格式</BaseQuizOption>
<BaseQuizAnswer><code>sub()</code> 方法用替换字符串替换模式的所有匹配项。它返回一个应用了替换的新字符串。</BaseQuizAnswer>
</BaseQuiz>

管理复杂的 Regexes

为了告诉 re.compile() 函数忽略正则表达式字符串中的空格和注释,“详细模式”可以通过将变量 re.VERBOSE 作为第二个参数传递给 re.compile() 来启用。

现在,而不是像这样难以阅读的正则表达式:

python
phone_regex = re.compile(r'((\d{3}|\(\d{3}\))?(\s|-|\.)?\d{3}(\s|-|\.)\d{4}(\s(ext|x|ext.)\s\d{2,5})?)')

您可以像这样将正则表达式分布在多行上并添加注释:

python
phone_regex = re.compile(r'''(
(\d{3}|\(\d{3}\))? # area code
(\s|-|\.)? # separator
\d{3} # first 3 digits
(\s|-|\.) # separator
\d{4} # last 4 digits
(\s(ext|x|ext.)\s\d{2,5})? # extension
)''', re.VERBOSE)

<BaseQuiz id="cheatsheet-regular-expressions-4" correct="A">
<template #question>
传递给 <code>re.compile()</code> 的 <code>re.VERBOSE</code> 会做什么?
</template>

<BaseQuizOption value="A" correct>A. 允许在 regex 模式中使用空格和注释以提高可读性</BaseQuizOption>
<BaseQuizOption value="B">B. 使 regex 忽略大小写</BaseQuizOption>
<BaseQuizOption value="C">C. 使点字符匹配换行符</BaseQuizOption>
<BaseQuizOption value="D">D. 加快 regex 匹配速度</BaseQuizOption>
<BaseQuizAnswer><code>re.VERBOSE</code> 标志允许您在正则表达式模式中添加空格和注释,使复杂的正则表达式更具可读性,同时不影响模式匹配。</BaseQuizAnswer>
</BaseQuiz>

相关链接

- <router-link to="/cheatsheet/manipulating-strings">字符串操作</router-link>
- <router-link to="/cheatsheet/string-formatting">字符串格式化</router-link>
- <router-link to="/blog/python-data-types">Python 数据类型博客文章</router-link>
- <router-link to="/builtin/compile">compile()</router-link>

---

Cheatsheet/Zh/Sets

---
title: 'Python 集合 - Python 速查表'
description: 'Python 内置了多种数据类型来帮助我们组织数据,这些结构包括列表、字典、元组和集合。'
labUrl: 'https://labex.io/zh/labs/python-python-sets-633665?course=python-cheatsheet'
---

<base-title :title="frontmatter.title" :description="frontmatter.description">
Python 集合 (Sets)
</base-title>

<base-lab-url :url="frontmatter.labUrl" />

Python 配备了几种内置数据类型来帮助我们组织数据。这些结构包括列表 (lists)、字典 (dictionaries)、元组 (tuples) 和集合 (sets)

<base-disclaimer>
<base-disclaimer-title>
来自 Python 3 <a target="_blank" href="https://docs.python.org/3/tutorial/datastructures.html#sets">文档</a>
</base-disclaimer-title>
<base-disclaimer-content>
集合是无序的、不包含重复元素的集合。基本用途包括成员资格测试和消除重复条目。
</base-disclaimer-content>
</base-disclaimer>

阅读 <router-link to="/blog/python-sets-what-why-how">Python 集合:是什么、为什么和如何使用</router-link> 以获得更深入的参考。

初始化集合

创建集合有两种方法:使用花括号 {} 和内置函数 set()

<base-warning>
<base-warning-title>
空集合
</base-warning-title>
<base-warning-content>
创建集合时,请确保不要使用空花括号 <code>{}</code>,否则您将得到一个空字典。
</base-warning-content>
</base-warning>

python

使用花括号或 set() 函数创建集合


s = {1, 2, 3} # 使用花括号
s = set([1, 2, 3]) # 使用 set() 构造函数

警告:空 {} 创建一个字典,而不是一个集合


s = {} # 这将创建一个字典而不是一个集合
type(s) # 返回 <class 'dict'>

output
<class 'dict'>

唯一元素的无序集合

集合会自动删除所有重复的值。

python

集合会自动删除重复项


s = {1, 2, 3, 2, 3, 4} # 重复项被删除
s # 返回 {1, 2, 3, 4}

output
{1, 2, 3, 4}

<BaseQuiz id="cheatsheet-sets-1" correct="A">
<template #question>
当你创建一个包含重复值的集合时会发生什么?
</template>

<BaseQuizOption value="A" correct>A. 重复项被自动删除</BaseQuizOption>
<BaseQuizOption value="B">B. 抛出错误</BaseQuizOption>
<BaseQuizOption value="C">C. 集合保留所有重复项</BaseQuizOption>
<BaseQuizOption value="D">D. 只保留第一次出现的</BaseQuizOption>
<BaseQuizAnswer>集合会自动删除重复的值。集合是无序的、不包含重复元素的集合。</BaseQuizAnswer>
</BaseQuiz>

并且由于它是一种无序数据类型,因此不能对其进行索引。

python
s = {1, 2, 3}
s[0]

output
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: 'set' object does not support indexing

集合的添加和更新 (add and update)

使用 add() 方法我们可以向集合中添加单个元素。

python

add() 方法:向集合中添加单个元素


s = {1, 2, 3}
s.add(4) # 添加元素 4
s

output
{1, 2, 3, 4}

使用 update(),可以添加多个元素:

python

update() 方法:从可迭代对象中添加多个元素


s = {1, 2, 3}
s.update([2, 3, 4, 5, 6]) # 添加多个元素(忽略重复项)
s

output
{1, 2, 3, 4, 5, 6}

集合的移除和丢弃 (remove and discard)

这两种方法都会从集合中移除一个元素,但如果值不存在,remove() 会引发 key error

python

remove() 方法:移除元素,如果找不到则引发 KeyError


s = {1, 2, 3}
s.remove(3) # 移除元素 3
s

output
{1, 2}

python
s.remove(3)

output
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
KeyError: 3

discard() 不会引发任何错误。

python

discard() 方法:移除元素,如果找不到则不报错


s = {1, 2, 3}
s.discard(3) # 移除元素 3 (安全,缺失时不报错)
s

output
{1, 2}

python
s.discard(3)

<BaseQuiz id="cheatsheet-sets-2" correct="C">
<template #question>
<code>remove()</code> 和 <code>discard()</code> 方法在集合上的区别是什么?
</template>

<BaseQuizOption value="A">A. <code>remove()</code> 移除一个元素,<code>discard()</code> 移除所有</BaseQuizOption>
<BaseQuizOption value="B">B. 没有区别</BaseQuizOption>
<BaseQuizOption value="C" correct>C. 如果元素不存在,<code>remove()</code> 抛出错误,<code>discard()</code> 不会</BaseQuizOption>
<BaseQuizOption value="D">D. <code>remove()</code> 更快</BaseQuizOption>
<BaseQuizAnswer>这两种方法都从集合中移除一个元素,但如果元素不存在,<code>remove()</code> 会引发 <code>KeyError</code>,而 <code>discard()</code> 如果元素缺失则不做任何操作。</BaseQuizAnswer>
</BaseQuiz>

集合的并集 (union)

union()| 将创建一个包含所有提供集合中所有元素的新集合。

python

union():组合来自多个集合的所有元素(无重复项)


s1 = {1, 2, 3}
s2 = {3, 4, 5}
s1.union(s2) # 或 's1 | s2' - 返回 {1, 2, 3, 4, 5}

output
{1, 2, 3, 4, 5}

集合的交集 (intersection)

intersection()& 将返回一个只包含所有集合中共同元素的集合。

python

intersection():返回所有集合共有的元素


s1 = {1, 2, 3}
s2 = {2, 3, 4}
s3 = {3, 4, 5}
s1.intersection(s2, s3) # 或 's1 & s2 & s3' - 返回 {3}

output
{3}

<BaseQuiz id="cheatsheet-sets-3" correct="B">
<template #question>
<code>intersection()</code> 返回集合的什么?
</template>

<BaseQuizOption value="A">A. 所有集合中的所有元素</BaseQuizOption>
<BaseQuizOption value="B" correct>B. 仅包含所有集合中共同的元素</BaseQuizOption>
<BaseQuizOption value="C">C. 第一个集合中存在但其他集合中不存在的元素</BaseQuizOption>
<BaseQuizOption value="D">D. 存在于任一集合中但不同时存在于两者中的元素</BaseQuizOption>
<BaseQuizAnswer><code>intersection()</code> 方法返回一个集合,其中仅包含存在于所有比较集合中的元素。</BaseQuizAnswer>
</BaseQuiz>

集合的差集 (difference)

difference()- 将只返回第一个集合(被调用的集合)中独有的元素。

python

difference():返回第一个集合中存在但其他集合中不存在的元素


s1 = {1, 2, 3}
s2 = {2, 3, 4}

s1.difference(s2) # 或 's1 - s2' - 返回 {1}

output
{1}

python
s2.difference(s1) # 或 's2 - s1'

output
{4}

集合的对称差集 (symmetric_difference)

symmetric_difference()^ 将返回所有不共同的元素。

python

symmetric_difference():返回存在于任一集合中但不同时存在于两者中的元素


s1 = {1, 2, 3}
s2 = {2, 3, 4}
s1.symmetric_difference(s2) # 或 's1 ^ s2' - 返回 {1, 4}

output
{1, 4}

<BaseQuiz id="cheatsheet-sets-4" correct="D">
<template #question>
<code>symmetric_difference()</code> 返回两个集合的什么?
</template>

<BaseQuizOption value="A">A. 两个集合中的所有元素</BaseQuizOption>
<BaseQuizOption value="B">B. 仅包含两个集合中共同的元素</BaseQuizOption>
<BaseQuizOption value="C">C. 第一个集合中存在但第二个集合中不存在的元素</BaseQuizOption>
<BaseQuizOption value="D" correct>D. 存在于任一集合中但不同时存在于两者中的元素</BaseQuizOption>
<BaseQuizAnswer><code>symmetric_difference()</code> 方法返回一个集合,其中包含存在于任一集合中,但不同时存在于两个集合中的元素。</BaseQuizAnswer>
</BaseQuiz>

相关链接

- <router-link to="/blog/python-data-types">Python 数据类型博客文章</router-link>
- <router-link to="/blog/python-sets-what-why-how">Python 集合:是什么、为什么和如何使用</router-link>
- <router-link to="/cheatsheet/dictionaries">Python 字典 (Dictionaries)</router-link>
- <router-link to="/cheatsheet/lists-and-tuples">Python 列表和元组 (Lists and Tuples)</router-link>

---

Cheatsheet/Zh/String Formatting

---
title: 'Python 字符串格式化 - Python 速查表'
description: '如果您使用 Python 3.6+,f-string 是推荐的字符串格式化方法。'
labUrl: 'https://labex.io/zh/labs/python-python-string-formatting-633667?course=python-cheatsheet'
---

<base-title :title="frontmatter.title" :description="frontmatter.description">
Python 字符串格式化
</base-title>

<base-lab-url :url="frontmatter.labUrl" />

<base-disclaimer>
<base-disclaimer-title>
来自 <a href="https://docs.python.org/3/library/stdtypes.html?highlight=sprintf#printf-style-string-formatting">Python 3 文档</a>
</base-disclaimer-title>
<base-disclaimer-content>
这里描述的格式化操作(<b>% 运算符</b>)表现出各种怪癖,导致许多常见错误 […]。使用较新的 <a href="#formatted-string-literals-or-f-strings">格式化字符串字面量</a> […] 有助于避免这些错误。这些替代方案还为文本格式化提供了更强大、更灵活和可扩展的方法。
</base-disclaimer-content>
</base-disclaimer>

% operator

<base-warning>
<base-warning-title>
首选字符串字面量
</base-warning-title>
<base-warning-content>
对于新代码,强烈建议使用 <a href="#strformat">str.format</a> 或 <a href="#formatted-string-literals-or-f-strings">格式化字符串字面量</a> (Python 3.6+) 而不是 <code>%</code> 运算符。
</base-warning-content>
</base-warning>

python

% operator: 旧式字符串格式化(不推荐用于新代码)


name = 'Pete'
'Hello %s' % name # %s = 字符串占位符

output
"Hello Pete"

我们可以使用 %d 格式说明符将 int 值转换为字符串:

python
num = 5
'I have %d apples' % num

output
"I have 5 apples"

str.format

Python 3 引入了一种新的字符串格式化方式,后来向后移植到 Python 2.7。这使得字符串格式化的语法更加规范。

python

str.format() 方法:现代字符串格式化 (Python 2.7+)


name = 'John'
age = 20

"Hello I'm {}, my age is {}".format(name, age) # {} = 占位符

output
"Hello I'm John, my age is 20"

python
"Hello I'm {0}, my age is {1}".format(name, age)

output
"Hello I'm John, my age is 20"

Formatted String Literals or f-Strings

如果使用 Python 3.6+,字符串 f-Strings 是格式化字符串的推荐方式。

<base-disclaimer>
<base-disclaimer-title>
来自 <a href="https://docs.python.org/3/reference/lexical_analysis.html#f-strings">Python 3 文档</a>
</base-disclaimer-title>
<base-disclaimer-content>
格式化字符串字面量或 f 字符串是前缀为 <code>f</code> 或 <code>F</code> 的字符串字面量。这些字符串可以包含替换字段,即由花括号 {} 分隔的表达式。虽然其他字符串字面量总是具有恒定值,但格式化字符串实际上是在运行时求值的表达式。
</base-disclaimer-content>
</base-disclaimer>

python

f-string: 格式化字符串的推荐方式 (Python 3.6+)


name = 'Elizabeth'
f'Hello {name}!' # f 前缀允许在 {} 中使用表达式

output
'Hello Elizabeth!'

<BaseQuiz id="cheatsheet-string-formatting-1" correct="B">
<template #question>
Python 中 f-string 使用的前缀是什么?
</template>

<BaseQuizOption value="A">A. <code>fmt</code></BaseQuizOption>
<BaseQuizOption value="B" correct>B. <code>f</code> 或 <code>F</code></BaseQuizOption>
<BaseQuizOption value="C">C. <code>format</code></BaseQuizOption>
<BaseQuizOption value="D">D. <code>str</code></BaseQuizOption>
<BaseQuizAnswer>f-string 前面有 <code>f</code> 或 <code>F</code> 后跟引号。它们允许您在花括号 <code>{}</code> 中嵌入表达式。</BaseQuizAnswer>
</BaseQuiz>

它甚至可以在其中进行内联算术运算:

python

f-strings 支持表达式:可以在 {} 内部包含计算


a = 5
b = 10
f'Five plus ten is {a + b} and not {2 * (a + b)}.' # 评估表达式

output
'Five plus ten is 15 and not 30.'

多行 f-Strings

python
name = 'Robert'
messages = 12
(
f'Hi, {name}. '
f'You have {messages} unread messages'
)

output
'Hi, Robert. You have 12 unread messages'

= 说明符

这将打印表达式及其值:

python

= 说明符:打印变量名和值 (Python 3.8+)


from datetime import datetime
now = datetime.now().strftime("%b/%d/%Y - %H:%M:%S")
f'date and time: {now=}' # 打印 "now='Nov/14/2022 - 20:50:01'"

output
"date and time: now='Nov/14/2022 - 20:50:01'"

添加空格或字符

python
name = 'Robert'
f"{name.upper() = :-^20}"

output
'name.upper() = -------ROBERT-------'

python
f"{name.upper() = :^20}"

output
'name.upper() =        ROBERT       '

python
f"{name.upper() = :20}"

output
'name.upper() = ROBERT              '

格式化数字

添加千位分隔符

python
a = 10000000
f"{a:,}"

output
'10,000,000'

四舍五入

python
a = 3.1415926
f"{a:.2f}"

output
'3.14'

<BaseQuiz id="cheatsheet-string-formatting-2" correct="C">
<template #question>
<code>f"{a:.2f}"</code> 的作用是什么?
</template>

<BaseQuizOption value="A">A. 将数字四舍五入到最接近的整数</BaseQuizOption>
<BaseQuizOption value="B">B. 格式化为百分比</BaseQuizOption>
<BaseQuizOption value="C" correct>C. 将数字格式化为带有 2 位小数的浮点数</BaseQuizOption>
<BaseQuizOption value="D">D. 转换为科学记数法</BaseQuizOption>
<BaseQuizAnswer>格式说明符 <code>:.2f</code> 将数字格式化为具有精确 2 位小数的浮点数。<code>.2</code> 指定精度,<code>f</code> 表示浮点格式。</BaseQuizAnswer>
</BaseQuiz>

显示为百分比

python
a = 0.816562
f"{a:.2%}"

output
'81.66%'

数字格式化表

| 数字 | 格式 | 输出 | 描述 |
| ---------- | ------- | --------- | ------------------------------------- |
| 3.1415926 | {:.2f} | 3.14 | 格式化浮点数,保留 2 位小数 |
| 3.1415926 | {:+.2f} | +3.14 | 格式化浮点数,保留 2 位小数并显示符号 |
| -1 | {:+.2f} | -1.00 | 格式化浮点数,保留 2 位小数并显示符号 |
| 2.71828 | {:.0f} | 3 | 格式化浮点数,不保留小数位 |
| 4 | {:0>2d} | 04 | 用零填充数字(左填充,宽度为 2) |
| 4 | {:x<4d} | 4xxx | 用 x 填充数字(右填充,宽度为 4) |
| 10 | {:x<4d} | 10xx | 用 x 填充数字(右填充,宽度为 4) |
| 1000000 | {:,} | 1,000,000 | 带逗号分隔符的数字格式 |
| 0.35 | {:.2%} | 35.00% | 格式化百分比 |
| 1000000000 | {:.2e} | 1.00e+09 | 指数表示法 |
| 11 | {:11d} | 11 | 右对齐(默认,宽度为 10) |
| 11 | {:<11d} | 11 | 左对齐(宽度为 10) |
| 11 | {:^11d} | 11 | 居中对齐(宽度为 10) |

Template Strings

一种更简单、功能较弱的机制,但在处理用户生成的字符串时推荐使用。由于其复杂性较低,模板字符串是更安全的选择。

python
from string import Template
name = 'Elizabeth'
t = Template('Hey $name!')
t.substitute(name=name)

output
'Hey Elizabeth!'

相关链接

- <router-link to="/cheatsheet/manipulating-strings">操作字符串</router-link>
- <router-link to="/blog/python-data-types">Python 数据类型博客文章</router-link>
- <router-link to="/builtin/format">format()</router-link>
- <router-link to="/builtin/print">print()</router-link>
- <router-link to="/builtin/str">str()</router-link>
- <router-link to="/builtin/repr">repr()</router-link>
- <router-link to="/builtin/ascii">ascii()</router-link>

---

Cheatsheet/Zh/Virtual Environments

---
title: 'Python 虚拟环境 - Python 速查表'
description: '使用虚拟环境是为了在隔离环境中测试 Python 代码,并避免用仅供单个项目使用的库填充基础 Python 安装。'
labUrl: 'https://labex.io/zh/labs/python-python-virtual-environments-633669?course=python-cheatsheet'
---

<base-title :title="frontmatter.title" :description="frontmatter.description">
虚拟环境
</base-title>

<base-lab-url :url="frontmatter.labUrl" />

使用虚拟环境的目的是在封装的环境中测试 Python 代码,并避免用仅用于一个项目的库填充基础 Python 安装。

venv

venv 是 Python 3.3+ 中用于创建虚拟环境的标准库模块。它内置于 Python 中,因此无需安装。

1. 创建一个虚拟环境

bash
python -m venv venv

或者在某些系统上:

bash
python3 -m venv venv

这将在当前文件夹中创建一个包含虚拟环境的 venv 目录。

<BaseQuiz id="cheatsheet-virtual-environments-1" correct="A">
<template #question>
使用 <code>venv</code> 创建虚拟环境的命令是什么?
</template>

<BaseQuizOption value="A" correct>A. <code>python -m venv venv</code></BaseQuizOption>
<BaseQuizOption value="B">B. <code>python create venv</code></BaseQuizOption>
<BaseQuizOption value="C">C. <code>venv create</code></BaseQuizOption>
<BaseQuizOption value="D">D. <code>python venv new</code></BaseQuizOption>
<BaseQuizAnswer>命令 <code>python -m venv venv</code> 创建一个虚拟环境。<code>-m</code> 标志运行 venv 模块,末尾的 <code>venv</code> 是要创建的目录的名称。</BaseQuizAnswer>
</BaseQuiz>

2. 激活虚拟环境

在 Linux/macOS 上:

bash
source venv/bin/activate

在 Windows 上:

bash
venv\Scripts\activate

激活后,您将在命令提示符的开头看到 (venv),表示虚拟环境已激活。

<BaseQuiz id="cheatsheet-virtual-environments-2" correct="B">
<template #question>
如何在 Linux/macOS 上激活虚拟环境?
</template>

<BaseQuizOption value="A">A. <code>activate venv</code></BaseQuizOption>
<BaseQuizOption value="B" correct>B. <code>source venv/bin/activate</code></BaseQuizOption>
<BaseQuizOption value="C">C. <code>venv activate</code></BaseQuizOption>
<BaseQuizOption value="D">D. <code>python venv activate</code></BaseQuizOption>
<BaseQuizAnswer>在 Linux/macOS 上,使用 <code>source venv/bin/activate</code> 激活虚拟环境。在 Windows 上,您将使用 <code>venv\Scripts\activate</code>。</BaseQuizAnswer>
</BaseQuiz>

3. 安装包

激活虚拟环境后,使用 pip 安装包:

bash
pip install package_name

安装的包将特定于此虚拟环境。

4. 停用虚拟环境

要退出虚拟环境:

bash
deactivate

命令提示符中的 (venv) 前缀将消失。

<BaseQuiz id="cheatsheet-virtual-environments-3" correct="A">
<template #question>
使用虚拟环境的主要目的是什么?
</template>

<BaseQuizOption value="A" correct>A. 隔离项目依赖项并避免填充基础 Python 安装</BaseQuizOption>
<BaseQuizOption value="B">B. 使 Python 运行得更快</BaseQuizOption>
<BaseQuizOption value="C">C. 加密 Python 代码</BaseQuizOption>
<BaseQuizOption value="D">D. 将 Python 编译成机器码</BaseQuizOption>
<BaseQuizAnswer>虚拟环境允许您在封装的环境中测试 Python 代码,并避免用可能仅用于一个项目的库填充基础 Python 安装。这有助于按项目管理依赖项。</BaseQuizAnswer>
</BaseQuiz>

virtualenv

1. 安装 virtualenv

bash
pip install virtualenv

1. 安装 virtualenvwrapper-win (Windows)

bash
pip install virtualenvwrapper-win

用法:

1. 创建一个名为 HelloWorld 的虚拟环境

bash
mkvirtualenv HelloWorld

现在安装的任何内容都将特定于此项目。并且可供我们连接到此环境的项目使用。

1. 设置项目目录

要将我们的 virtualenv 与当前工作目录绑定,我们只需输入:

bash
setprojectdir .

1. 停用

要在命令行中进行其他操作,请键入 deactivate 以停用您的环境。

bash
deactivate

注意括号如何消失。

1. Workon

打开命令提示符并键入 workon HelloWorld 以激活环境并进入项目根文件夹

bash
workon HelloWorld

Poetry

<base-disclaimer>
<base-disclaimer-title>
来自 <a href="https://python-poetry.org/">Poetry 网站</a>
</base-disclaimer-title>
<base-disclaimer-content>
Poetry 是一个用于 Python 中依赖管理和打包的工具。它允许您声明项目所依赖的库,它将为您管理(安装/更新)它们。
</base-disclaimer-content>
</base-disclaimer>

1. 安装 Poetry

bash
pip install --user poetry

2. 创建一个新项目

bash
poetry new my-project

这将创建一个 my-project 目录:

plaintext
my-project
├── pyproject.toml
├── README.rst
├── poetry_demo
│ └── __init__.py
└── tests
├── __init__.py
└── test_poetry_demo.py

pyproject.toml 文件将协调您的项目及其依赖项:

toml
[tool.poetry]
name = "my-project"
version = "0.1.0"
description = ""
authors = ["your name <[email protected]>"]

[tool.poetry.dependencies]
python = "*"

[tool.poetry.dev-dependencies]
pytest = "^3.4"

3. 包

要向项目中添加依赖项,您可以在 tool.poetry.dependencies 部分指定它们:

toml
[tool.poetry.dependencies]
pendulum = "^1.4"

此外,您可以不手动修改 pyproject.toml 文件,而是使用 add 命令,它会自动找到合适的版本约束。

bash
poetry add pendulum

要安装 pyproject.toml 中列出的依赖项:

bash
poetry install

要删除依赖项:

bash
poetry remove pendulum

有关更多信息,请查看文档或在此处阅读:

- <router-link to="/blog/python-projects-with-poetry-and-vscode-part-1">使用 Poetry 和 VSCode 的 Python 项目。第 1 部分</router-link>
- <router-link to="/blog/python-projects-with-poetry-and-vscode-part-2">使用 Poetry 和 VSCode 的 Python 项目。第 2 部分</router-link>
- <router-link to="/blog/python-projects-with-poetry-and-vscode-part-3">使用 Poetry 和 VSCode 的 Python 项目。第 3 部分</router-link>

Pipenv

<base-disclaimer>
<base-disclaimer-title>
来自 <a target="_blank" href="https://pipenv.pypa.io/en/latest/">Pipenv 网站</a>
</base-disclaimer-title>
<base-disclaimer-content>
Pipenv 是一个旨在将所有打包世界(bundler、composer、npm、cargo、yarn 等)中最好的部分带到 Python 世界的工具。Windows 在我们的世界中是首等公民。
</base-disclaimer-content>
</base-disclaimer>

1. 安装 pipenv

bash
pip install pipenv

2. 进入您的项目目录并安装项目的包

bash
cd my_project
pipenv install <package>

Pipenv 将安装您的包并在项目目录中为您创建一个 Pipfile。Pipfile 用于跟踪项目所需的依赖项,以防您需要重新安装它们。

3. 卸载包

bash
pipenv uninstall <package>

4. 激活与您的 Python 项目关联的虚拟环境

bash
pipenv shell

5. 退出虚拟环境

bash
exit

docs.pipenv.org 查找更多信息和视频。

Anaconda

<base-disclaimer>
<base-disclaimer-title>
<a target="k" href="https://anaconda.com/">Anaconda</a> 是另一个流行的 Python 包管理工具。
</base-disclaimer-title>
<base-disclaimer-content>
在这里共享包、notebook、项目和环境。您免费公开托管 conda 包的地方。
</base-disclaimer-content>
</base-disclaimer>

用法:

1. 创建一个虚拟环境

bash
conda create -n HelloWorld

2. 要使用虚拟环境,请通过以下方式激活它:

bash
conda activate HelloWorld

现在安装的任何内容都将特定于 HelloWorld 项目

3. 退出虚拟环境

bash
conda deactivate

UV

<base-disclaimer>
<base-disclaimer-title>
来自 <a target="_blank" href="https://docs.astral.sh/uv/">UV 文档</a>
</base-disclaimer-title>
<base-disclaimer-content>
UV 是一个极其快速的 Python 包安装程序和解析器,设计为 pip 和 pip-tools 工作流程的直接替代品。UV 比 pip 快 10-100 倍,并提供统一的包管理、虚拟环境创建和 Python 版本管理。
</base-disclaimer-content>
</base-disclaimer>

1. 安装 UV

bash

使用 curl (Linux/macOS)


curl -LsSf https://astral.sh/uv/install.sh | sh

使用 pip 或 pipx


pip install uv

2. 创建一个带有虚拟环境的新项目

bash
uv init my-project
cd my-project

3. 添加依赖项

bash
uv add requests

4. 在项目环境中运行命令

bash
uv run python script.py

5. 手动激活虚拟环境(可选)

bash
source .venv/bin/activate  # Linux/macOS
.venv\Scripts\activate # Windows

UV 以卓越的速度和便利性自动管理虚拟环境、Python 版本和依赖项。

相关链接

- <router-link to="/cheatsheet/packaging">打包</router-link>
- <router-link to="/blog/python-projects-with-poetry-and-vscode-part-1">使用 Poetry 和 VSCode 的 Python 项目。第 1 部分</router-link>
- <router-link to="/blog/python-projects-with-poetry-and-vscode-part-2">使用 Poetry 和 VSCode 的 Python 项目。第 2 部分</router-link>
- <router-link to="/blog/python-projects-with-poetry-and-vscode-part-3">使用 Poetry 和 VSCode 的 Python 项目。第 3 部分</router-link>
- <router-link to="/blog/python-uv-package-manager">UV:闪电般快速的 Python 包管理器</router-link>
- <router-link to="/builtin/import">import()</router-link>

---

Cheatsheet/Ru/Args And Kwargs

---
title: 'Python Args и Kwargs – Шпаргалка по Python'
description: 'Args и kwargs могут показаться сложными, но на самом деле их легко понять. Они придают функциям гибкость и улучшают читаемость кода.'
labUrl: 'https://labex.io/ru/labs/python-python-args-and-kwargs-633646?course=python-cheatsheet'
---

<base-title :title="frontmatter.title" :description="frontmatter.description">
Аргументы и Kwargs Python
</base-title>

<base-lab-url :url="frontmatter.labUrl" />

<base-disclaimer>
<base-disclaimer-title>
<a href="https://docs.python.org/3/tutorial/index.html">Python args and kwargs Made Easy</a>
</base-disclaimer-title>
<base-disclaimer-content>
<code>args</code> и <code>*kwargs</code> могут показаться пугающими, но правда в том, что их не так уж сложно понять, и они могут наделить ваши функции большой гибкостью.
</base-disclaimer-content>
</base-disclaimer>

Прочтите статью <router-link to="/blog/python-easy-args-kwargs">Python \args и \\*kwargs Made Easy</router-link> для более глубокого введения.

Args и Kwargs

args и *kwargs позволяют передавать неопределенное количество позиционных и именованных аргументов при вызове функции.

python

Define a function that accepts any number of positional and keyword arguments


def some_function(args, *kwargs):
pass

Call with any number of positional arguments


some_function(arg1, arg2, arg3)

Call with any number of keyword arguments


some_function(key1=arg1, key2=arg2, key3=arg3)

Call with both positional and keyword arguments


some_function(arg, key1=arg1)

Or call with no arguments at all


some_function()

<base-warning>
<base-warning-title>
Python conventions
</base-warning-title>
<base-warning-content>
Слова <code>args</code> и <code>*kwargs</code> являются соглашениями. Они не навязываются интерпретатором, но считаются хорошей практикой в сообществе Python.
</base-warning-content>
</base-warning>

args

Вы можете получить доступ к _аргументам_ через переменную args:

python

*args collects positional arguments into a tuple


def some_function(*args):
print(f'Arguments passed: {args} as {type(args)}')

Pass multiple arguments - they'll be collected into args tuple


some_function('arg1', 'arg2', 'arg3')

output
Arguments passed: ('arg1', 'arg2', 'arg3') as <class 'tuple'>

<BaseQuiz id="cheatsheet-args-and-kwargs-1" correct="B">
<template #question>
В какой тип данных собираются аргументы <code>*args</code>?
</template>

<BaseQuizOption value="A">A. Список</BaseQuizOption>
<BaseQuizOption value="B" correct>B. Кортеж (tuple)</BaseQuizOption>
<BaseQuizOption value="C">C. Словарь</BaseQuizOption>
<BaseQuizOption value="D">D. Множество (set)</BaseQuizOption>
<BaseQuizAnswer>Параметр <code>\*args</code> собирает позиционные аргументы в кортеж. Это позволяет функции принимать любое количество позиционных аргументов.</BaseQuizAnswer>
</BaseQuiz>

kwargs

Именованные аргументы (keywords) доступны через переменную kwargs:

python

kwargs collects keyword arguments into a dictionary


def some_function(kwargs):
print(f'keywords: {kwargs} as {type(kwargs)}')

Pass keyword arguments - they'll be collected into kwargs dict


some_function(key1='arg1', key2='arg2')

output
keywords: {'key1': 'arg1', 'key2': 'arg2'} as <class 'dict'>

<BaseQuiz id="cheatsheet-args-and-kwargs-2" correct="C">
<template #question>
В какой тип данных собираются аргументы <code>kwargs</code>?
</template>

<BaseQuizOption value="A">A. Список</BaseQuizOption>
<BaseQuizOption value="B">B. Кортеж (tuple)</BaseQuizOption>
<BaseQuizOption value="C" correct>C. Словарь</BaseQuizOption>
<BaseQuizOption value="D">D. Множество (set)</BaseQuizOption>
<BaseQuizAnswer>Параметр <code>\\kwargs</code> собирает именованные аргументы в словарь. Это позволяет функции принимать любое количество именованных аргументов.</BaseQuizAnswer>
</BaseQuiz>

- <router-link to="/cheatsheet/functions">Функции</router-link>
- <router-link to="/cheatsheet/lists-and-tuples">Списки и Кортежи</router-link>
- <router-link to="/cheatsheet/dictionaries">Словари Python</router-link>
- <router-link to="/blog/python-easy-args-kwargs">Python \args и \\*kwargs Made Easy</router-link>
- <router-link to="/builtin/tuple">tuple()</router-link>
- <router-link to="/builtin/dict">dict()</router-link>

---

Cheatsheet/Ru/Basics

---
title: 'Основы Python - Шпаргалка по Python'
description: 'Изучите основы Python с помощью нашего подробного руководства, охватывающего операторы, типы данных, переменные, функции и многое другое. Идеально подходит для начинающих, изучающих основы программирования на Python.'
labUrl: 'https://labex.io/ru/labs/python-python-basics-633647?course=python-cheatsheet'
---

<base-title :title="frontmatter.title" :description="frontmatter.description">
Основы Python
</base-title>

<base-lab-url :url="frontmatter.labUrl" />

Всем нам нужно с чего-то начинать, так почему бы не начать здесь. Это руководство охватывает фундаментальные основы Python, включая операторы, типы данных, переменные и основные функции.

<base-disclaimer>
<base-disclaimer-title>
Обзор основ Python
</base-disclaimer-title>
<base-disclaimer-content>
Основные основы Python, которые должен знать каждый новичок:

- Переменные и базовые типы
- Операторы и выражения
- Строки и общие методы
- Списки, кортежи и словари
- Базовый поток управления (if, for, while)
- Простые функции

</base-disclaimer-content>
</base-disclaimer>

Математические операторы

От наивысшего к низшему приоритету:

| Операторы | Операция | Пример |
| --------- | --------------------- | --------------- |
| \\ | Возведение в степень | 2 3 = 8 |
| % | Остаток от деления | 22 % 8 = 6 |
| // | Целочисленное деление | 22 // 8 = 2 |
| / | Деление | 22 / 8 = 2.75 |
| \ | Умножение | 3 3 = 9 |
| - | Вычитание | 5 - 2 = 3 |
| + | Сложение | 2 + 2 = 4 |

Примеры выражений:

python

Умножение имеет более высокий приоритет, чем сложение


Поэтому это вычисляется как: 2 + (3 * 6) = 2 + 18 = 20


2 + 3 * 6

output
20

python

Скобки переопределяют приоритет операторов


Это вычисляется как: 5 * 6 = 30


(2 + 3) * 6

output
30

python
2  8

output
256

python
23 // 7

output
3

python
23 % 7

output
2

python
(5 - 1) * ((7 + 1) / (3 - 1))

output
16.0

<BaseQuiz id="cheatsheet-basics-1" correct="A">
<template #question>
Каков результат этого выражения Python?

python
4 + 2 * 3

</template>

<BaseQuizOption value="A" correct>A. 10</BaseQuizOption>
<BaseQuizOption value="B">B. 18</BaseQuizOption>
<BaseQuizOption value="C">C. 12</BaseQuizOption>
<BaseQuizOption value="D">D. 20</BaseQuizOption>
<BaseQuizAnswer>Умножение имеет более высокий приоритет, чем сложение, поэтому это вычисляется как: 4 + (2 \* 3) = 4 + 6 = 10</BaseQuizAnswer>
</BaseQuiz>

Операторы присваивания с расширением

| Оператор | Эквивалент |
| ----------- | ---------------- |
| var += 1 | var = var + 1 |
| var -= 1 | var = var - 1 |
| var = 1 | var = var 1 |
| var /= 1 | var = var / 1 |
| var //= 1 | var = var // 1 |
| var %= 1 | var = var % 1 |
| var = 1 | var = var 1 |

Примеры:

python

Присваивание с расширением: эквивалентно greeting = greeting + ' world!'


greeting = 'Hello'
greeting += ' world!'
greeting

output
'Hello world!'

python

Увеличить число на 1


number = 1
number += 1
number

output
2

python

Повторение элементов списка: эквивалентно my_list = my_list * 3


my_list = ['item']
my_list *= 3
my_list

output
['item', 'item', 'item']

<BaseQuiz id="cheatsheet-basics-2" correct="B">
<template #question>
Каково значение <code>x</code> после выполнения этого кода?

python
x = 5
x += 3

</template>

<BaseQuizOption value="A">A. 3</BaseQuizOption>
<BaseQuizOption value="B" correct>B. 8</BaseQuizOption>
<BaseQuizOption value="C">C. 5</BaseQuizOption>
<BaseQuizOption value="D">D. 15</BaseQuizOption>
<BaseQuizAnswer>Оператор присваивания с расширением <code>+=</code> эквивалентен <code>x = x + 3</code>. Таким образом, <code>x</code> начинается с 5, а затем становится 5 + 3 = 8.</BaseQuizAnswer>
</BaseQuiz>

Оператор "Морж" (Walrus Operator)

Оператор "Морж" позволяет присваивать переменные внутри выражения, возвращая при этом значение переменной

Пример:

python

Оператор "Морж" присваивает и возвращает значение в одном выражении


my_var присваивается "Hello World!" и затем выводится на печать


print(my_var:="Hello World!")

output
Hello World!

python
my_var="Yes"
print(my_var)

output
Yes

python
print(my_var:="Hello")

output
Hello

Оператор _"Морж"_, или Оператор выражения присваивания, был впервые представлен в 2018 году через PEP 572, а затем официально выпущен с Python 3.8 в октябре 2019 года.

<base-disclaimer>
<base-disclaimer-title>
Синтаксическая семантика и примеры
</base-disclaimer-title>
<base-disclaimer-content>
PEP 572 предоставляет синтаксис, семантику и примеры для оператора "Морж".
</base-disclaimer-content>
</base-disclaimer>

Типы данных

Понимание типов данных — одна из самых важных основ Python. В Python есть девять основных встроенных типов данных, которые охватывают почти все, что вам понадобится:

| Тип данных | Примеры | Описание |
| ---------------------------------------------------------- | ---------------------------------------- | ---------------------------------------------- |
| Числа | | |
| <router-link to='/builtin/int'>int</router-link> | -2, -1, 0, 1, 2, 3, 4, 5 | Целые числа |
| <router-link to='/builtin/float'>float</router-link> | -1.25, -1.0, -0.5, 0.0, 0.5, 1.0, 1.25 | Числа с десятичной точкой |
| <router-link to='/builtin/complex'>complex</router-link> | 2+3j, complex(1, 4) | Числа с действительной и мнимой частями |
| Текст | | |
| <router-link to='/builtin/str'>str</router-link> | 'a', 'Hello!', "Python" | Текст и символы |
| Булевы | | |
| <router-link to='/builtin/bool'>bool</router-link> | True, False | Значения Истина или Ложь |
| None | | |
| NoneType | None | Обозначает "нет значения" или "ничего" |
| Коллекции | | |
| <router-link to='/builtin/list'>list</router-link> | [1, 2, 3], ['a', 'b', 'c'] | Упорядоченные, изменяемые коллекции |
| <router-link to='/builtin/dict'>dict</router-link> | {'name': 'Alice', 'age': 30} | Пары ключ-значение |
| <router-link to='/builtin/tuple'>tuple</router-link> | (1, 2, 3), ('a', 'b') | Упорядоченные, неизменяемые коллекции |
| <router-link to='/builtin/set'>set</router-link> | {1, 2, 3}, {'a', 'b', 'c'} | Неупорядоченные коллекции уникальных элементов |

Краткие примеры

python

Числа


age = 25 # int
price = 19.99 # float
coordinate = 2 + 3j # complex

Текст


name = "Alice" # str

Булевы


is_student = True # bool

None


result = None # NoneType

Коллекции


scores = [85, 92, 78] # list
person = {'name': 'Bob', 'age': 30} # dict
coordinates = (10, 20) # tuple
unique_ids = {1, 2, 3} # set

Для всеобъемлющего руководства с визуальными примерами и подробными объяснениями о том, когда использовать каждый тип, см.: <router-link to="/blog/python-data-types">Типы данных Python: Визуальное руководство для начинающих</router-link>.

Конкатенация и повторение

Конкатенация строк:

python

Конкатенация строк: смежные строки автоматически объединяются


'Alice' 'Bob'

output
'AliceBob'

Повторение строк:

python

Повторение строк: повторить строку несколько раз


'Alice' * 5

output
'AliceAliceAliceAliceAlice'

Переменные

Переменные — это фундаментальная часть основ Python. Вы можете назвать переменную как угодно, если она подчиняется следующим правилам:

1. Она может состоять только из одного слова.

python

плохо


my variable = 'Hello'

хорошо


var = 'Hello'

2. Она может содержать только буквы, цифры и символ подчеркивания (_).

python

плохо


%$@variable = 'Hello'

хорошо


my_var = 'Hello'

хорошо


my_var_2 = 'Hello'

3. Она не может начинаться с цифры.

python

это не сработает


23_var = 'hello'

4. Имя переменной, начинающееся с подчеркивания (_), считается "неиспользуемым".

python

_spam не следует использовать снова в коде


_spam = 'Hello'

<BaseQuiz id="cheatsheet-basics-3" correct="C">
<template #question>
В основах Python, какое из следующих имен является допустимым именем переменной?
</template>

<BaseQuizOption value="A">A. <code>3value</code></BaseQuizOption>
<BaseQuizOption value="B">B. <code>user-name</code></BaseQuizOption>
<BaseQuizOption value="C" correct>C. <code>user_name</code></BaseQuizOption>
<BaseQuizOption value="D">D. <code>for</code></BaseQuizOption>
<BaseQuizAnswer><code>user_name</code> является допустимым именем переменной, поскольку оно использует только буквы, цифры и подчеркивания и не начинается с цифры.</BaseQuizAnswer>
</BaseQuiz>

Комментарии

Встроенный комментарий:

python

Это комментарий

Многострочный комментарий:

python

Это


многострочный комментарий

Код с комментарием:

python
a = 1  # инициализация

Обратите внимание на два пробела перед комментарием.

Строка документации функции:

python
def foo():
"""
Это строка документации функции
Вы также можете использовать:
''' Строка документации функции '''
"""

Функция print()

Функция print() — одна из первых основ Python, которую вы изучите. Она выводит значение переданного ей аргумента(ов). [...] она обрабатывает несколько аргументов, числа с плавающей запятой и строки. Строки печатаются без кавычек, и между элементами вставляется пробел, так что вы можете красиво форматировать вывод:

python
print('Hello world!')

output
Hello world!

python
a = 1
print('Hello world!', a)

output
Hello world! 1

Ключевое слово end

Ключевой аргумент end можно использовать, чтобы избежать перехода на новую строку после вывода, или завершить вывод другой строкой:

python

Используйте параметр end, чтобы изменить то, что идет после каждого оператора print


phrase = ['printed', 'with', 'a', 'dash', 'in', 'between']
for word in phrase:
print(word, end='-') # Используем '-' вместо новой строки

output
printed-with-a-dash-in-between-

Ключевое слово sep

Ключевое слово sep определяет, как разделять объекты, если их несколько:

python

Используйте параметр sep, чтобы указать разделитель между несколькими аргументами


print('cats', 'dogs', 'mice', sep=',') # Вывод с разделителем-запятой

output
cats,dogs,mice

Функция input()

Эта функция принимает ввод от пользователя и преобразует его в строку:

python

input() считывает ввод пользователя и возвращает его в виде строки


print('What is your name?') # запрашиваем имя
my_name = input() # Ожидаем, пока пользователь введет текст и нажмет Enter
print('Hi, {}'.format(my_name))

output
What is your name?
Martha
Hi, Martha

input() также может отображать сообщение-подсказку без использования print():

python
my_name = input('What is your name? ')  # сообщение-подсказка
print('Hi, {}'.format(my_name))

output
What is your name? Martha
Hi, Martha

Также возможно использовать форматированные строки, чтобы избежать использования .format:

python

input() может отображать сообщение-подсказку напрямую


my_name = input('What is your name? ') # Подсказка и чтение в одном вызове
print(f'Hi, {my_name}') # f-строка для форматирования строк

output
What is your name? Martha
Hi, Martha

<BaseQuiz id="cheatsheet-basics-4" correct="B">
<template #question>
В основах Python, какой тип возвращает input()?
</template>

<BaseQuizOption value="A">A. int</BaseQuizOption>
<BaseQuizOption value="B" correct>B. str</BaseQuizOption>
<BaseQuizOption value="C">C. float</BaseQuizOption>
<BaseQuizOption value="D">D. Зависит от ввода пользователя</BaseQuizOption>
<BaseQuizAnswer>Функция <code>input()</code> всегда возвращает строку, независимо от того, что вводит пользователь. Вам нужно преобразовать ее в другой тип, если это необходимо.</BaseQuizAnswer>
</BaseQuiz>

Функция len()

Оценивается в целое число, равное количеству символов в строке, списке, словаре и т. д.:

python

len() возвращает количество символов в строке


len('hello') # Возвращает 5

output
5

python

len() возвращает количество элементов в списке


len(['cat', 3, 'dog']) # Возвращает 3 (три элемента)

output
3

<base-warning>
<base-warning-title>Проверка на пустоту</base-warning-title>
<base-warning-content>
Проверку на пустоту строк, списков, словарей и т. д. не следует выполнять с помощью
<code>len</code>, а лучше предпочесть прямую булеву оценку.
</base-warning-content>
</base-warning>

Пример проверки на пустоту:

python
a = [1, 2, 3]

плохо: ненужная проверка len()


if len(a) > 0: # оценивается как True
print("the list is not empty!")

output
the list is not empty!

python

хорошо: прямая булева оценка (Pythonic способ)


if a: # оценивается как True, если список не пуст
print("the list is not empty!")

output
the list is not empty!

Функции str(), int() и float()

Эти функции позволяют изменять тип переменной. Например, вы можете преобразовать integer или float в string:

python

Преобразовать целое число в строку


str(29) # Возвращает '29'

output
'29'

python
str(-3.14)

output
'-3.14'

Или из string в integer или float:

python

Преобразовать строку в целое число


int('11') # Возвращает 11

output
11

python

Преобразовать строку в число с плавающей точкой


float('3.14') # Возвращает 3.14

output
3.14

<BaseQuiz id="cheatsheet-basics-5" correct="C">
<template #question>
Каков результат этого кода Python?

python
result = int('42')
type(result)

</template>

<BaseQuizOption value="A">A. <code>str</code></BaseQuizOption>
<BaseQuizOption value="B">B. <code>float</code></BaseQuizOption>
<BaseQuizOption value="C" correct>C. <code>int</code></BaseQuizOption>
<BaseQuizOption value="D">D. <code>NoneType</code></BaseQuizOption>
<BaseQuizAnswer>Функция <code>int()</code> преобразует строку в целое число. Таким образом, <code>int('42')</code> возвращает целое число <code>42</code>, а <code>type(42)</code> возвращает <code>int</code>.</BaseQuizAnswer>
</BaseQuiz>

Связанные ссылки

- <router-link to="/blog/python-data-types">Типы данных Python: Визуальное руководство для начинающих</router-link>
- <router-link to="/blog/python-comprehensions-step-by-step">Пошаговое руководство по генераторам Python</router-link>
- <router-link to="/cheatsheet/control-flow">Поток управления</router-link>
- <router-link to="/cheatsheet/functions">Функции</router-link>
- <router-link to="/cheatsheet/lists-and-tuples">Списки и кортежи</router-link>
- <router-link to="/cheatsheet/dictionaries">Словари</router-link>
- <router-link to="/cheatsheet/sets">Множества</router-link>
- <router-link to="/cheatsheet/string-formatting">Форматирование строк</router-link>

---

Cheatsheet/Ru/Built In Functions

---
title: 'Встроенные функции Python - Справочник Python'
description: 'Интерпретатор Python содержит ряд функций и типов, которые всегда доступны.'
labUrl: 'https://labex.io/ru/labs/python-python-built-in-functions-633648?course=python-cheatsheet'
---

<base-title :title="frontmatter.title" :description="frontmatter.description">
Встроенные функции Python
</base-title>

<base-lab-url :url="frontmatter.labUrl" />

Интерпретатор Python имеет ряд встроенных функций и типов, которые всегда доступны.

Встроенные функции Python

| Функция | Описание |
| -------------------------------------------------------------------- | ----------------------------------------------------------------------------------------- |
| <router-link to='/builtin/abs'>abs()</router-link> | Возвращает абсолютное значение числа. |
| <router-link to='/builtin/aiter'>aiter()</router-link> | Возвращает асинхронный итератор для асинхронной итерируемой коллекции. |
| <router-link to='/builtin/all'>all()</router-link> | Возвращает True, если все элементы итерируемой коллекции истинны. |
| <router-link to='/builtin/any'>any()</router-link> | Возвращает True, если хотя бы один элемент итерируемой коллекции истинен. |
| <router-link to='/builtin/ascii'>ascii()</router-link> | Возвращает строку с печатным представлением объекта. |
| <router-link to='/builtin/bin'>bin()</router-link> | Преобразует целое число в двоичную строку. |
| <router-link to='/builtin/bool'>bool()</router-link> | Возвращает логическое значение. |
| <router-link to='/builtin/breakpoint'>breakpoint()</router-link> | Переводит вас в отладчик в месте вызова. |
| <router-link to='/builtin/bytearray'>bytearray()</router-link> | Возвращает новый массив байтов. |
| <router-link to='/builtin/bytes'>bytes()</router-link> | Возвращает новый объект “bytes”. |
| <router-link to='/builtin/callable'>callable()</router-link> | Возвращает True, если аргумент объекта вызываемый, False в противном случае. |
| <router-link to='/builtin/chr'>chr()</router-link> | Возвращает строку, представляющую символ. |
| <router-link to='/builtin/classmethod'>classmethod()</router-link> | Преобразует метод в классовый метод. |
| <router-link to='/builtin/compile'>compile()</router-link> | Компилирует исходный код в объект кода или AST. |
| <router-link to='/builtin/complex'>complex()</router-link> | Возвращает комплексное число со значением real + imag\*1j. |
| <router-link to='/builtin/delattr'>delattr()</router-link> | Удаляет именованный атрибут, если объект это разрешает. |
| <router-link to='/builtin/dict'>dict()</router-link> | Создает новый словарь. |
| <router-link to='/builtin/dir'>dir()</router-link> | Возвращает список имен в текущей локальной области видимости. |
| <router-link to='/builtin/divmod'>divmod()</router-link> | Возвращает пару чисел, состоящую из частного и остатка. |
| <router-link to='/builtin/enumerate'>enumerate()</router-link> | Возвращает объект перечисления. |
| <router-link to='/builtin/eval'>eval()</router-link> | Вычисляет и выполняет выражение. |
| <router-link to='/builtin/exec'>exec()</router-link> | Эта функция поддерживает динамическое выполнение кода Python. |
| <router-link to='/builtin/filter'>filter()</router-link> | Создает итератор из итерируемой коллекции, возвращающий истинные элементы. |
| <router-link to='/builtin/float'>float()</router-link> | Возвращает число с плавающей запятой из числа или строки. |
| <router-link to='/builtin/format'>format()</router-link> | Преобразует значение в “форматированное” представление. |
| <router-link to='/builtin/frozenset'>frozenset()</router-link> | Возвращает новый объект frozenset. |
| <router-link to='/builtin/getattr'>getattr()</router-link> | Возвращает значение именованного атрибута объекта. |
| <router-link to='/builtin/globals'>globals()</router-link> | Возвращает словарь, реализующий текущее пространство имен модуля. |
| <router-link to='/builtin/hasattr'>hasattr()</router-link> | Возвращает True, если у объекта есть именованный атрибут. |
| <router-link to='/builtin/hash'>hash()</router-link> | Возвращает хеш-значение объекта. |
| <router-link to='/builtin/help'>help()</router-link> | Запускает встроенную систему справки. |
| <router-link to='/builtin/hex'>hex()</router-link> | Преобразует целое число в шестнадцатеричную строку в нижнем регистре. |
| <router-link to='/builtin/id'>id()</router-link> | Возвращает “идентичность” объекта. |
| <router-link to='/builtin/input'>input()</router-link> | Эта функция принимает ввод и преобразует его в строку. |
| <router-link to='/builtin/int'>int()</router-link> | Возвращает целочисленный объект, созданный из числа или строки. |
| <router-link to='/builtin/isinstance'>isinstance()</router-link> | Возвращает True, если аргумент объекта является экземпляром объекта. |
| <router-link to='/builtin/issubclass'>issubclass()</router-link> | Возвращает True, если класс является подклассом classinfo. |
| <router-link to='/builtin/iter'>iter()</router-link> | Возвращает объект итератора. |
| <router-link to='/builtin/len'>len()</router-link> | Возвращает длину (количество элементов) объекта. |
| <router-link to='/builtin/list'>list()</router-link> | Является не функцией, а изменяемым типом последовательности. |
| <router-link to='/builtin/locals'>locals()</router-link> | Обновляет и возвращает словарь с текущей локальной таблицей символов. |
| <router-link to='/builtin/map'>map()</router-link> | Возвращает итератор, применяющий функцию к каждому элементу итерируемой коллекции. |
| <router-link to='/builtin/max'>max()</router-link> | Возвращает наибольший элемент в итерируемой коллекции. |
| <router-link to='/builtin/min'>min()</router-link> | Возвращает наименьший элемент в итерируемой коллекции. |
| <router-link to='/builtin/next'>next()</router-link> | Извлекает следующий элемент из итератора. |
| <router-link to='/builtin/object'>object()</router-link> | Возвращает новый объект без особенностей. |
| <router-link to='/builtin/oct'>oct()</router-link> | Преобразует целое число в восьмеричную строку. |
| <router-link to='/builtin/open'>open()</router-link> | Открывает файл и возвращает соответствующий файловый объект. |
| <router-link to='/builtin/ord'>ord()</router-link> | Возвращает целое число, представляющее кодовую точку Unicode символа. |
| <router-link to='/builtin/pow'>pow()</router-link> | Возвращает base в степени exp. |
| <router-link to='/builtin/print'>print()</router-link> | Выводит объекты в текстовый поток файла. |
| <router-link to='/builtin/property'>property()</router-link> | Возвращает атрибут свойства. |
| <router-link to='/builtin/repr'>repr()</router-link> | Возвращает строку, содержащую печатное представление объекта. |
| <router-link to='/builtin/reversed'>reversed()</router-link> | Возвращает обратный итератор. |
| <router-link to='/builtin/round'>round()</router-link> | Возвращает число, округленное до ndigits знаков после запятой. |
| <router-link to='/builtin/set'>set()</router-link> | Возвращает новый объект set. |
| <router-link to='/builtin/setattr'>setattr()</router-link> | Это аналог getattr(). |
| <router-link to='/builtin/slice'>slice()</router-link> | Возвращает объект среза, представляющий набор индексов. |
| <router-link to='/builtin/sorted'>sorted()</router-link> | Возвращает новый отсортированный список из элементов итерируемой коллекции. |
| <router-link to='/builtin/staticmethod'>staticmethod()</router-link> | Преобразует метод в статический метод. |
| <router-link to='/builtin/str'>str()</router-link> | Возвращает строковую версию объекта. |
| <router-link to='/builtin/sum'>sum()</router-link> | Суммирует start и элементы итерируемой коллекции. |
| <router-link to='/builtin/super'>super()</router-link> | Возвращает прокси-объект, делегирующий вызовы методов родительскому или соседнему классу. |
| <router-link to='/builtin/tuple'>tuple()</router-link> | Является не функцией, а неизменяемым типом последовательности. |
| <router-link to='/builtin/type'>type()</router-link> | Возвращает тип объекта. |
| <router-link to='/builtin/vars'>vars()</router-link> | Возвращает атрибут dict для любого другого объекта с атрибутом dict. |
| <router-link to='/builtin/zip'>zip()</router-link> | Итерирует по нескольким итерируемым коллекциям параллельно. |
| <router-link to='/builtin/import'>import()</router-link> | Эта функция вызывается оператором import. |

---