2023年的“绝对初学者”完整的Python教程
#初学者 #教程 #python #course

Python是一种令人难以置信的强大编程语言,在世界各地生产系统中数以百万计的开发人员使用。它很容易学习,可以自由使用,并且拥有众多的开发人员社区,这些开发人员始终愿意提供帮助。

如果您对back-end web development,数据科学,data engineering或只是想自动化一些无聊的任务,Python是一个很好的起点。

您愿意通过做吗?

我在本教程中包括了您需要的所有静态读取材料,但是如果您想要更多的动手体验,您可以使用此互动版本当然,在Boot.dev here上进行编码挑战和项目。

第1章:简介

python

成千上万的学生开始在这里与Python一起在这里进行编码之旅。我们认为这是开始使用的最好的编程语言。 Python以易于读写的简单语言而闻名。

但是,仅仅因为它很简单,这并不意味着它没有用! Python是行业中极为流行语言的一种,并以:

而闻名。
  • 后端Web服务器
  • DevOps和Cloud Engineering
  • 机器学习
  • 脚本和自动化
  • 等...

另一方面,这并不是在前端工作中特别闻名的。虽然可以这样做是可能的,但python通常不用于构建视觉用户界面。

设置当地开发环境

要开始使用Python,您需要在计算机上安装python命令,然后安装文本编辑器或IDE。如果您还不熟悉如何做到这一点,那么我可以遵循一个完整的分步project guide here

如果您能够在计算机上编辑和运行Python代码,则可以继续!

什么是“代码”?

代码只是计算机可以遵循的一系列说明。计算机遵守每个指令,一个接一个地

程序可以由许多指令组成。像许多人一样。像数百万。

添加是编码中最常见的说明之一。

打印数字

print()可以使用引号打印文本:

print("some text here")

,但它也可以打印数字而没有引号:

print(1)

您可以直接在括号内进行数学:

print(1 + 2)

在编辑器中尝试其中一些代码段!例如,您可以创建一个名为hello.py的文件并编写以下代码:

print("Hello, world!")
print(1 + 2)

然后,使用python hello.py运行文件,看看会发生什么。

多个说明

代码按顺序运行,从程序的顶部开始。例如:

print("this prints first")
print("this prints second")
print("this prints last")

语法错误

Syntax是“计算机可以理解的有效代码”的术语。例如,

prnt("hello world")

是无效的syntax,因为prnt()不是一个有效的功能,因此“打印”是错误的。结果,将抛出错误,并且代码将不会执行。

语法从langauge到语言不等

编码语言的语法构成了定义该语言中结构适当的表达式和语句的规则。例如,在Python中,以下内容将被视为正确语法:

print("hello world")

使用不同的编程语言(例如GO),正确的语法将是:

fmt.Println("hello world")

代码可能会有许多不同的问题,可以防止其按预期工作。一些示例包括:

  • 逻辑中的错误。例如,一个应该添加数字的程序将它们乘以它们
  • 速度的问题。一个计算如何打出象棋完美游戏的程序可能永远无法完成,因为它需要太多的计算。
  • 语法问题。对于新开发人员来说,这是最常见的问题。幸运的是,Python解释器将尝试在控制台中为您提供描述性错误消息,以帮助您找到问题。

第2章:变量

Variables是我们在程序中存储数据的方式。到目前为止,我们一直通过将数据直接传递到print()函数直接打印数据。

现在,我们将学习将数据保存在变量中,以便我们可以在需要打印之前将其使用和更改。

变量是我们定义的名称,它将指向某些数据。例如,我可以定义一个称为my_height的新变量,并将其值设置为100。我还可以定义一个称为my_name的变量,并将其设置为“车道”。

创建变量

要在Python中创建一个新变量,我们使用以下语法:

my_new_variable_two = 2
this_can_be_called_anything = 3

变量各不相同

变量称为“变量”,因为它们可以保持任何值,并且该值可以改变(它变化)。

例如,以下将打印20

acceleration = 10
acceleration = 20
print(acceleration)

acceleration = 20 reassigns acceleration至20的值。

让我们做一些数学

现在我们知道如何存储和更改变量的价值,让我们进行一些数学!

这是Python语法中常见数学运算符的一些示例。

sum = a + b
difference = a - b
product = a * b
quotient = a / b

评论

注释不会像代码那样运行,它们被计算机忽略。评论对于添加提醒或解释一件代码用普通英语的代码很有用。

单行评论

# speed is a variable describing how fast your player moves
speed = 2

多行评论(又名Docstrings)

您也可以使用三重引号开始和结束多行评论:

"""
    the code found below 
    will print 'Hello, World!' to the console
"""
print('Hello, World!')

如果您不想在编写评论段落时将#添加到每行的开始。

可变名称

变量名称不能有空格,它们是字符的连续字符串。

在Python中,您应该在创建变量名称时使用“ snake_case” - 它已成为该语言的“经验法则”。相比之下,“骆驼盒”是每个新词的开头,除了第一个。

没有套管(纯粹的精神错乱)

somevariablehere = 10

骆驼香烟盒

someVariableHere = 10

蛇案

some_variable_here = 10

基本变量类型

在Python中有几种基本数据类型。

字符串类型

“字符串”是编码说话的原始文本。它们被称为“字符串”,因为它们是串在一起的角色列表。通过使用单引号或双引号在Python中声明字符串。也就是说,为了一致性,我们更喜欢双引号。

name_with_single_quotes = 'boot.dev'
name_with_double_quotes = "boot.dev"

数字类型

创建时的数字不会被引号包围,但是它们可能有小数和负迹象。

整数是没有小数的数字

x = 5
y = -5

一个“ float”是一个十进制的数字

x = 5.2
y = -5.2

布尔类型

“布尔”(或“布尔”)是一种只能具有两个值之一:TrueFalse。正如您可能听到的那样,计算机实际上只使用1和0。这些1和0只是Boolean值。

0 = False
1 = True
is_tall = True

非类型变量

并非所有变量都有一个值。我们可以通过将其设置为None来声明“空”变量。

empty = None

在这种情况下,empty的值是None,直到我们使用分配运算符=给它一个值。

没有特定的字符串

请注意,None类型是不是与“无”值的字符串相同:

my_none = None # this is a None-type
my_none = "None" # this is a string

动态键入

Python是dynamically typed。所有这些意味着变量可以存储任何类型,并且该类型可以更改。

例如,如果我做一个数字变量,则以后可以将该变量更改为字符串:

这是有效的:

speed = 5
speed = "five"

仅仅因为你可以说你应该!

在几乎所有情况下,更改变量的类型是一个坏主意。要做的“正确”的事情就是创建一个新的事情。例如:

speed = 5
speed_description = "five"

如果没有动态键入该怎么办?

像GO这样的静态键入语言(在以后的课程中您会学到的)是静态键入的,而不是动态键入的。在静态键入的语言中,如果您尝试将值分配给错误类型的变量,则错误将崩溃。

如果Python静态型,则第一个示例将在第二行崩溃,speed = "five"。计算机会沿着you can't assign a string value ("five") to a number variable (speed)

的线路出现错误

用字符串数学

除了+加法运营商外,我们早些时候曾经过的大多数数学运算符都不使用字符串。使用字符串时,+操作员执行“串联”。

“串联”是一个花哨的词,意味着两个字符串的连接。

first_name = "Lane "
last_name = "Wagner"
full_name = first_name + last_name

full_name现在拥有“车道瓦格纳”的值。

请注意first_name变量中"Lane "末端的额外空间。在最终结果中,还有额外的空间将单词分开:"Lane Wagner"

多变量声明

通过在同一行上声明它们来创建许多新变量时,我们可以节省空间:

sword_name, sword_damage, sword_length = "Excalibur", 10, 200

与:
相同

sword_name = "Excalibur"
sword_damage = 10
sword_length = 200

可以在同一行上声明任何数量的变量,并且在同一行上声明的变量应以某种方式相互关联,以便代码仍然易于理解。

我们调用易于理解“干净代码”的代码。

第2章:计算基础知识

python数字

在Python中,没有小数零件的数字称为Integers-就像它们在数学中一样。

整数只是全数字,正数或负数。例如,3-3都是整数的示例。

算术可以按照您的期望进行:

添加

2 + 1
# 3

减法

2 - 1
# 1

乘法

2 * 2
# 4

分配

3 / 2
# 1.5 (a float)

这个实际上有些不同 - 两个整数上的除法实际上会产生一个float。正如您可能猜到的那样,浮子是允许小数值的数字类型。

整数

在Python中,没有小数零件的数字称为Integers。将其与JavaScript进行对比,所有数字只是Number类型。

整数只是全数字,正数或负数。例如,3-3都是整数的示例。

浮子

您可能已经猜到的是允许小数值的数字类型。

my_int = 5
my_float = 5.5

地板师

Python对数学操作有很好的开箱即用支持。除其他原因外,为什么它在人工智能,机器学习和数据科学应用中取得了如此成功的原因。

地板分裂就像正常的划分,但结果是floored之后,这意味着剩余的已删除。如您所料,这意味着结果是integer而不是float

7 // 3
# 2 (an integer)

指数

python对指数有内置的支持 - 大多数语言都需要math库。

# reads as "three squared" or
# "three raised to the second power"
3 ** 2
# 9

在适当的位置

想要根据其当前值更改变量的值是很常见的。

player_score = 4
player_score = player_score + 1
# player_score now equals 5
player_score = 4
player_score = player_score - 1
# player_score now equals 3

不要让表达式player_score = player_score - 1不是有效的数学表达的事实令人困惑。 这没关系是有效的代码。这是有效的,因为应该用英语读取表达方式是:

分配给player_score player_score减去1

的旧值

加上平等

python在进行数学时使重新分配变得容易。在JavaScript或Go中,您可能熟悉++语法,以增加数字变量。在Python中,我们使用+=操作员。

star_rating = 4
star_rating += 1
# star_rating is now 5

科学计数法

正如我们之前涵盖的那样,float是一个正数或负数,分数部分

您可以添加字母eE,然后是一个正或负整数来指定您使用的是scientific notation

print(16e3)
# Prints 16000.0

print(7.1e-2)
# Prints 0.071

如果您不熟悉科学符号,这是一种表达数字太大或太小而无法正常写入的数字的方式。

简而

强调可读性

python还允许您使用下划线而不是逗号以更易于阅读的逗号表示大量数字。

num = 16_000
print(num)
# Prints 16000

num = 16_000_000
print(num)
# Prints 16000000

逻辑操作员

您可能熟悉逻辑运营商ANDOR

逻辑运营商处理boolean valuesTrueFalse

逻辑AND运算符要求 输入都是True才能返回True。逻辑OR操作员只要求至少一个输入是True才能返回True

例如:

True AND True = True
True AND False = False
False AND False = False

True OR True = True
True OR False = True
False OR False = False

Python语法

print(True and True)
# prints True

print(True or False)
# prints True

用括号嵌套

我们可以使用括号嵌套逻辑表达式。

print((True or False) and False)

首先,我们评估了括号中的表达,(True or False)。它评估为True

print(True and False)

True and False评估对False

print(False)

所以,print((True or False) and False)向控制台打印“ false”。

二进制数

二进制数字只是“基本2”数字。它们的工作方式与“普通”基础10个数字相同,但是有2个符号而不是10个符号。

二进制数中的每个1代表2个较大的倍数。在4位数字中,这意味着您拥有八个位置,四个位置,四个位置,两人的位置和一个位置。类似于您在十进制中如何拥有千分之一的位置,一百个位置,十个位置和一个地方。

  • 0001 = 1
  • 0010 = 2
  • 0011 = 3
  • 0100 = 4
  • 0101 = 5
  • 0110 = 6
  • 0111 = 7
  • 1000 = 8

binary

钻头”&”操作员

位运算符与逻辑运算符相似,但是它们不用在布尔值上操作,而是将相同的逻辑应用于值中的所有位。例如,假设您的数字57binary中代表。您可以执行Bitwise AND操作,结果将是5

0101 = 5
&
0111 = 7
=
0101 = 5

二进制中的1True相同,而0False。因此,实际上是一个位于串联完成的逻辑操作。

&是Python中的Bitwise AND操作员。 5 & 7 = 5,而5 & 2 = 0

0101 = 5
&
0010 = 2
=
0000 = 0

二进制符号

在二进制中编写一个数字时,前缀0b用于指示下面的是二进制号码。

  • 0b0101是5
  • 0b0111是7

示例:公会许可

在后端开发中,将用户权限存储为二进制值是常见的做法。考虑一下,如果我拥有用户可以拥有的4不同的权限,那么我可以将其存储为4位二进制号码,如果存在某个位置,我知道已启用了权限。

让我们假装我们有4个权限:

  • can_create_guild-最左边的位
  • can_review_guild-第二到左
  • can_delete_guild-第二到右
  • can_edit_guild-最右边的位

0b0000代表。例如,如果用户仅拥有can_create_guild许可,则其二进制权限为0b1000。拥有can_review_guildcan_edit_guild的用户将是0b0101

要检查can_review_guild许可,我们可以对用户的权限和启用的can_review_guild bit(0b0100)执行Bitwise AND操作。如果结果再次为0b0100,我们知道他们已有特定的许可!

钻头“ |”操作员

您可能已经猜到的是,位“或“操作员”类似于位”和“运算符,因为它在二进制而非布尔值上都起作用。但是,将位的位“或“操作员”)一起。这是一个例子:

  • 0101是5
  • 0111是7
0101
|     
0111
=
0111

二进制中的1True相同,而0False。因此,位操作只是一堆逻辑操作,这些操作是同时完成的。当两个二进制编号一起“ or”在一起时,结果在输入数字的任何位置都具有1

|是Python的Bitwise OR操作员。 5 | 7 = 75 | 2 = 7

0101 = 5
|
0010 = 2
=
0111 = 7

不是

我们跳过了一个非常重要的逻辑操作员-notnot操作员逆转了结果。如果输入为True,则返回False,反之亦然。

print(not True)
# Prints: False

print(not False)
# Prints: True

第3章:比较

比较操作员

编码时,有必要比较两个值。 Boolean logic是这些比较操作的名称,这些操作总是导致TrueFalse

操作员:

  • <“小于”
  • >“大于”
  • <=“小于或等于”
  • >=“大于或等于”
  • ==“等于”
  • !=“不等于”

例如:

5 < 6 # evaluates to True
5 > 6 # evaluates to False
5 >= 6 # evaluates to False
5 <= 6 # evaluates to True
5 == 6 # evaluates to False
5 != 6 # evaluates to True

评估

发生比较时,比较的结果只是一个布尔值,它是TrueFalse

以以下两个示例:

is_bigger = 5 > 4
is_bigger = True

在上述两种情况下,我们正在创建一个称为is_biggerBoolean变量,值为True

5 > 4以来,is_bigger总是分配了True的值。

如果可以将其设置为“ True”,为什么要使用比较?

您不会在 案例中。但是,让我们想象,我们没有一些 dynamic 变量,而不是用硬编码数字54。例如,也许您正在制作视频游戏,需要跟踪玩家分数。

要计算谁获胜,您需要写类似的东西:

# player_one_points and player_two_points are defined and change somewhere else in the game's code
player_one_wins = player_one_points > player_two_points
print(player_one_wins)

# prints "True" when player one is winning, otherwise prints "False"

增量 /减少

如果我们要更改一个数字,并且只想增加(添加到)或减少(从中减去),则有特殊操作员。

shield_armor = 4
shield_armor += 1
# shield_armor now equals 5
shield_armor += 2
# shield_armor now equals 7
shield_armor = 4
shield_armor -= 1
# shield_armor now equals 3
shield_armor -= 2
# shield_armor now equals 1

请注意,shield_armor+=1只是shield_armor = shield_armor + 1

的短手

如果语句

在满足特定条件时仅执行代码通常很有用:

if CONDITION:
  # do some stuff here

例如:

if bob_score > bill_score:
  print("Bob Wins!")

如果别的

if语句之后可以零或更多的elif(代表“ else if”)语句,可以随后进行零或一个else语句。例如:

if score > high_Score:
    print('High score beat!')
elif score > second_highest_score:
    print('You got second place!')
elif score > third_highest_score:
    print('You got third place!')
else:
    print('Better luck next time')

首先评估了if语句。如果是True,则执行IF语句的主体,并且所有其他else被忽略。

如果第一个if是错误的,则评估下一个elif。同样,如果是True,则执行其身体,其余的忽略。

如果if没有对True进行评估,则最终的else语句将是唯一执行的机构。

如果else规则

  • 没有ifelifelse
  • you can 有一个没有elifelse

第5章:循环

循环是程序员的最好朋友。循环允许我们多次进行相同的操作,而无需每次明确编写。

例如,让我们假装我想打印数字0-9。

我可以这样做:

print(0)
print(1)
print(2)
print(3)
print(4)
print(5)
print(6)
print(7)
print(8)
print(9)

即使这样,它也可以节省很多时间来使用 loop 。特别是如果我想做同样的事情 一百万次。

a “ for loop” 在python中是这样写的:

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

在英语中,代码说:

  1. i开始等于0。 (i in range(0
  2. 如果i不少于10(range(0, 10)),请退出循环。
  3. i打印到控制台。 (print(i)
  4. 1添加到i。 (range默认为1)
  5. 返回步骤2

结果是数字0-9按顺序记录到控制台。

空格在Python中很重要!

for-loop 必须缩进的主体,否则您会遇到语法错误。

例子

此代码将数字0-9打印到控制台。

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

范围继续

我们在for循环中使用的range()函数实际上具有可选的第三参数:“步骤”。

for i in range(0, 10, 2):
    print(i)
# prints:
# 0
# 2
# 4
# 6
# 8

“步骤”参数确定在循环的每次迭代中都要增加i的数量。您甚至可以向后走:

for i in range(3, 0, -1):
    print(i)
# prints:
# 3
# 2
# 1

python的F串

您可以通过在Python中使用f-strings创建具有动态值的字符串。这是我希望使用更多编程语言的美丽语法。

num_bananas = 10
print(f"You have {num_bananas} bananas")
# You have 10 bananas

需要由f进行开头报价,然后卷曲括号内的任何变量都将其值插入字符串中。

第6章:列表

自然的组织数据和存储数据的方式是List的形式。一些语言称它们为“数组”,但是在Python中,我们只是称它们为列表。想一想您使用的所有应用程序以及应用程序中的多少个项目都被组织到列表中。

例如:

  • Twitter提要是帖子列表
  • 在线商店是产品列表
  • 国际象棋游戏的状态是移动列表
  • 此列表是列表的清单

python中的列表使用方括号声明,逗号将每个项目分开:

inventory = ["Iron Breastplate", "Healing Potion", "Leather Scraps"]

数组可以包含任何数据类型的项目,在上面的示例中,我们有一个List字符串。

垂直语法

有时候,当我们手动创建列表时,如果所有项目都在同一行中,则很难阅读。如果要:
,我们可以使用多条线声明数组

flower_types = [
    "daffodil",
    "rose",
    "chrysanthemum"
]

请记住,这只是样式的变化。代码将正确运行任何一种方式。

在编程中计数

在编程世界中,计数有些奇怪!

我们不在1开始计数,而是从0开始。

索引

数组中的每个项目都有一个索引,指的是数组中的位置。

以以下数组为例:

names = ["Bob", "Lane", "Alice", "Breanna"]
  • 索引0:Bob
  • 索引1:Lane
  • 索引2:Alice
  • 索引3:Breanna

索引到列表

现在我们知道如何创建新列表,我们需要知道如何访问列表中的特定项目。

我们使用其 index 直接访问列表中的项目。索引从0(第一个项目)开始,并在每个连续项目中递增一个。语法如下:

best_languages = ["JavaScript", "Go", "Rust", "Python", "C"]
print(best_languages[1])
# prints "Go", because index 1 was provided

列表长度

可以使用len()函数来计算列表的长度。同样,我们稍后将详细介绍功能,但这是语法:

fruits = ["apple", "banana", "pear"]
length = len(fruits)
# Prints: 3

列表的长度等于目前的项目数。不要被长度不等于最后一个元素的索引的事实,实际上它永远是一个更大的事实。

列表更新

我们还可以更改给定索引处的项目。例如,我们可以通过以下方式将Leather更改为inventory数组中的Leather Armor

inventory = ["Leather", "Healing Potion", "Iron Ore"]
inventory[0] = "Leather Armor"
# inventory: ['Leather Armor', 'Healing Potion', 'Iron Ore']

在Python附加

通常创建一个空列表,然后使用循环填充值。我们可以使用.append()方法将值添加到列表的末尾:

cards = []
cards.append("nvidia")
cards.append("amd")
# the cards list is now ['nvidia', 'amd']

流行值

.pop().append()相反。 POP从数组中删除了最后一个元素,并将其返回供使用。例如:

vegetables = ["broccoli", "cabbage", "kale", "tomato"];
last_vegetable = vegetables.pop()
# vegetables = ['broccoli', 'cabbage', 'kale']
# last_vegetable = 'tomato'

计算列表中的项目

请记住,我们可以使用循环在数组中的所有项目上迭代(计数)。例如,以下代码将在sports数组中打印每个项目。

for i in range(0, len(sports)):
    print(sports[i])

无索引语法

我认为,Python具有直接在列表中的项目上迭代的最优雅语法,而不必担心索引编号。如果您不需要索引号,则可以使用以下语法:

trees = ['oak', 'pine', 'maple']
for tree in trees:
  print(tree)
# Prints:
# oak
# pine
# maple

tree,使用in关键字声明的变量,直接访问数组中的值,而不是值的索引。如果我们不需要更新该项目,并且只需要访问其值,那么这是编写代码的更干净的方法。

在列表中找到一个项目

“ no-index”或“无范围”语法的示例:

for fruit in fruits:
    print(fruit)

Python中的模块操作员

Modulo操作员可用于查找剩余部分:

例如,7 modulo 21,因为2最多可以均匀地乘以7次:

2 * 3 = 6

然后有1 剩下的67

7 - 6 = 1

D运算符是百分比:%。重要的是要识别Modulo 不是一个百分比!那只是我们正在使用的符号。

remainder = 8 % 3
# remainder = 2

一个奇数是一个数字,当除以2时,其余的是 0

切片列表

python可以轻松切片和骰子列表仅与您关心的部分一起使用。一种方法是使用简单的切片操作员,即仅是Colon :

使用此操作员,您可以指定从何处开始和结束切片,以及如何逐步浏览原始切片。列表切片从现有列表中返回新列表

语法如下:

Lst[ Initial : End : IndexJump ]
scores = [50, 70, 30, 20, 90, 10, 50]
# Display list
print(scores[1:5:2])
# Prints [70, 20]

上面的内容为“从索引1给我一个scores列表的切片,最多包括但不包括5,跳过每2个值。 所有部分都是可选的

scores = [50, 70, 30, 20, 90, 10, 50]
# Display list
print(scores[1:5])
# Prints [70, 30, 20, 90]
scores = [50, 70, 30, 20, 90, 10, 50]
# Display list
print(scores[1:])
# Prints [70, 30, 20, 90, 10, 50]

列表操作 - 串联

在python中,只需使用+操作员,将两个列表串联在一起(将它们切在一起)真的很容易。

all = [1, 2, 3] + [4, 5, 6]
print(all)
# Prints: [1, 2, 3, 4, 5, 6]

列表操作 - 包含

检查列表中是否存在一个值也很容易在Python中,只需使用in关键字。

fruits = ["apple", "orange", "banana"]
print("banana" in fruits)
# Prints: True

提示:报价中的报价

要在引号中使用引号,它们要么需要是escaped,要么需要使用其他类型的引号。因为我们通常使用双引号,所以我们可以用单语嵌套字符串:

f"banana is in fruits list: {'banana' in fruits}"

列表删除

Python具有一个内置的关键字del,可从对象中删除项目。在列表的情况下,您可以删除特定索引或整个切片。

nums = [1, 2, 3, 4, 5, 6, 7, 8, 9]

# delete the fourth item
del nums[3]
print(nums)
# Output: [1, 2, 3, 5, 6, 7, 8, 9]

# delete items from 2nd to 3rd
nums = [1, 2, 3, 4, 5, 6, 7, 8, 9]
del nums[1:3]
print(nums)
# Output: [1, 4, 5, 6, 7, 8, 9]

# delete all elements
nums = [1, 2, 3, 4, 5, 6, 7, 8, 9]
del nums[:]
print(nums)
# Output: []

元组

Tuples是订购和不变的数据集合。您可以将元组视为具有固定尺寸的List。用圆形支架创建元组:

my_tuple = ("this is a tuple", 45, True)
print(my_tuple[0])
# this is a tuple
print(my_tuple[1])
# 45
print(my_tuple[2])
# True

通常认为将不同类型的物品存储在列表中的不良习惯虽然不是元组的问题。因为它们的尺寸固定,所以很容易跟踪哪些数据类型的索引存储。

元组通常用于存储非常小的组(例如2或3个项目)。例如,您可能会使用元组来存储狗的名字和年龄。

dog = ("Fido", 4)

由于元组持有数据,因此可以将多个元组存储在列表中。类似于将其他数据存储在列表中,列表中的每个元组都由逗号分开。

my_tuples = [("this is the first tuple in the list", 45, True),("this is the second tuple in the list", 21, False)]
print(my_tuples[0][0])
# this is the first tuple in the list

第7章:功能

函数允许我们重复使用组织代码。例如,让我们假装我们需要计算一个圆的面积。我们可以使用公式area = pi * r^2或代码:

r = 5
area = 3.14 * r * r

这很好!当我们的代码中的多个位置需要获得一个圆圈的区域时,就会出现问题

r = 5
area1 = 3.14 * r * r

r2 = 7
area2 = 3.14 * r2 * r2

r3 = 11
area3 = 3.14 * r3 * r3

我们想使用相同的代码,为什么要重复工作?

让我们声明一个新功能area_of_circle()。请注意,def关键字是在函数名称之前编写的,并告诉计算机我们要声明或定义一个新功能。

def area_of_circle(r):
    return 3.14 * r * r

area_of_circle函数采用一个输入(也可以称为参数或参数),并返回单个输出。我们给我们的功能一个圆的半径,然后恢复了该圆的区域!

使用或“ call”我们可以以任何数字作为输入传递的功能,并将输出捕获到一个新变量中:

radius = 5
area = area_of_circle(radius)

让我们逐步通过此代码示例。

  1. radius变量是用5的值创建的。
  2. area_of_circle函数与单个参数:radius调用
  3. 执行area_of_circle功能,r等于5
  4. 3.14 * r * r的结果从area_of_circle返回,恰好是78.75
  5. area_of_circle(radius)解决了78.75的返回值
  6. area变量是创建的,它具有78.75的值

多个参数

函数可以具有多个参数,也可以输入:

def subtract(a, b):
    return a - b

在哪里声明功能

您可能已经注意到,在使用之前,需要在之前声明。例如,以下内容不起作用:

print(my_name)
my_name = 'Lane Wagner'

需要:

my_name = 'Lane Wagner'
print(my_name)

代码线以从上到下的顺序执行,因此需要创建一个变量,然后才能使用它。这意味着,如果您定义函数,则直到定义之后才能调用该函数。

main()函数是许多编程语言中使用的约定,以指定应用程序的入口点。通过定义单个main函数,并且仅在整个程序末尾调用main(),我们确保在调用所有函数之前都定义所有函数。

功能顺序

所有函数必须在使用之前定义

您可能会认为这会使构造Python代码变得困难

事实证明,大多数Python开发人员通过首先定义所有函数来解决此问题,然后最终调用Entrypoint函数last 。如果您这样做,则在中声明功能的顺序无关紧要。入口点函数通常称为“ main”。

def main():
    func2()

def func2():
    func3()

def func3():
    print("I'm function 3")

main() # entrypoint

范围

范围是指 可以使用变量或函数名称。例如,当我们在函数中创建变量时(例如,通过给我们的参数命名),该数据是 not 在该函数之外可用的。

例如:

def subtract(x, y)
    return x - y
result = subtract(5, 3)
print(x)
# ERROR! "name 'x' is not defined"

当调用subtract函数时,我们将变量x分配给5,但是x仅在 the subtract函数的代码中存在。如果我们尝试在该功能之外打印x,那么我们将不会得到结果,实际上我们会遇到一个很大的脂肪错误。

全球范围

到目前为止,我们一直在全球范围内工作。这意味着,当我们定义变量或函数时,该名称在我们程序中的其他位置也可以在其他功能中访问。

例如:

pi = 3.14

def get_area_of_circle(radius):
    return pi * radius * radius

因为在父“全局”范围中声明了pi,因此在get_area_of_circle()函数中可用。

无穷

内置的float()函数可用于创建代表负相值负值的numeric floating point value。我已经为您添加了它作为起点。

negative_infinity = float('-inf')
positive_infinity = float('inf')

没有返回

当函数中未指定返回值时(例如,它是将某些文本打印到控制台的函数,但不会明确返回值),它将返回None。以下代码片段都返回完全相同的内容:

def my_func():
    print("I do nothing")
    return None
def my_func():
    print("I do nothing")
    return
def my_func():
    print("I do nothing")

参数与参数

参数是当 demaning a函数时用于输入的名称。参数是函数

时提供的输入的名称。

要重申,参数是函数中的实际值,例如42.0"the dark knight"True。参数是我们在函数定义中使用的名称来指代那些值,在编写函数时可能是任何内容。

也就是说,重要的是要了解这是所有语义,坦率地说,开发人员对这些定义确实很懒惰。您经常会听到互换使用的文字参数和参数。

# a and b are parameters
def add(a, b)
    return a + b

# 5 and 6 are arguments
sum = add(5, 6)

多个返回值

在Python中,我们可以从函数中返回多个值。我们需要做的就是通过逗号分开每个值。

# returns email, age, and status of the user
def get_user():
    return "name@domain.com", 21, "active"

email, age, status = get_user()
print(email, age, status)
# Prints: "name@domain.com 21 active"
def get_user():
    return "name@domain.com", 21, "active"

# this works, and by convention you should NOT use the underscore variable later
email, _, _ = get_user()
print(email)
# Prints: "name@domain.com"
print(_)
# Prints: "active"

函数参数的默认值

python可以为函数参数指定默认值。如果一个函数具有本质上是“可选”的参数,并且您作为函数创建者想要使用特定默认值,以防呼叫者不提供一个

,这可能很方便。

通过使用函数签名中的分配(=)运算符创建默认值。

def get_greeting(email, name="there"):
    return f"Hello {name}, welcome! You've registered your email: {email}"
msg = get_greeting("lane@example.com", "Lane")
# Hello Lane, welcome! You've registered your email: lane@example.com
msg = get_greeting("lane@example.com")
# Hello there, welcome! You've registered your email: lane@example.com

如果省略了第二个参数,则将在其位置使用默认的"there"值。您可能已经猜到了,为了使该结构起作用,在所有必需的参数之后,已指定默认值的可选参数。

第8章:词典

python中的字典用于将数据值存储在key-> value对中。字典是存储信息组的好方法。

car = {
  "brand": "Tesla",
  "model": "3",
  "year": 2019
}

重复键

由于字典依赖于唯一的键,因此您在同一词典中不能拥有两个相同的密钥。如果您尝试两次使用相同的密钥,则相关值将被简单地覆盖。

访问字典值

字典元素必须在代码中以某种方式访问​​,否则它们不会很有用。

通过在方括号中指定其相应的键来从字典中检索一个值。语法看起来类似于索引到列表。

car = {
    'make': 'tesla',
    'model': '3'
}
print(car['make'])
# Prints: tesla

设置字典值

您不需要创建具有内部值的字典。通常创建一个空白字典,然后使用动态值填充它。语法与从密钥中获取数据相同,只需使用分配运算符(=)才能使该密钥具有值。

names = ["jack bronson", "jill mcarty", "john denver"]

names_dict = {}
for name in names:
    # .split() returns a list of strings
    # where each string is a single word from the original
    names_arr = name.split()

    # here we update the dictionary
    names_dict[names_arr[0]] = names_arr[1]

print(names_dict)
# Prints: {'jack': 'bronson', 'jill': 'mcarty', 'john': 'denver'}

更新字典值

如果您尝试设置已经存在的密钥的值,最终您只会更新该密钥的值。

names = ["jack bronson", "james mcarty", "john denver"]

names_dict = {}
for name in names:
    # .split() returns a list of strings
    # where each string is a single word from the original
    names_arr = name.split()

    # we're always setting the "jack" key
    names_dict["jack"] = names_arr[1]

print(names_dict)
# Prints: {'jack': 'denver'}

删除字典值

您可以使用del关键字删除现有的键。

names_dict = {
    'jack': 'bronson',
    'jill': 'mcarty',
    'joe': 'denver'
}

del names_dict['joe']

print(names_dict)
# Prints: {'jack': 'bronson', 'jill': 'mcarty'}

删除不存在的键

请注意,如果您尝试删除不存在的键,您将获得错误

names_dict = {
    'jack': 'bronson',
    'jill': 'mcarty',
    'joe': 'denver'
}

del names_dict['unknown']
# ERROR HERE, key doesn't exist

检查存在

如果您不确定字典中是否存在密钥,请使用in关键字。

cars = {
    'ford': 'f150',
    'tesla': '3'
}

print('ford' in cars)
# Prints: True

print('gmc' in cars)
# Prints: False

在python的字典上迭代

fruit_sizes = {
    "apple": "small",
    "banana": "large",
    "grape": "tiny"
}

for name in fruit_sizes:
    size = fruit_sizes[name]
    print(f"name: {name}, size: {size}")

# name: apple, size: small
# name: banana, size: large
# name: grape, size: tiny

订购还是无序?

从Python版本3.7开始,字典是 drounded 。在Python 3.6和更早的时候,字典是无序的

因为词典是订购的,这些项目具有定义的顺序,该顺序将 更改。

无序意味着用于 的项目具有定义的顺序,因此您无法使用索引来参考项目。

**要点是,如果您在Python 3.7或更高版本上,您每次都可以按照相同的顺序迭代字典。

第9章:集合

集合喜欢列表,但它们是无序的,它们保证了独特性。一组中没有两个相同值的两个。

fruits = {'apple', 'banana', 'grape'}
print(type(fruits))
# Prints: <class 'set'>

print(fruits)
# Prints: {'banana', 'grape', 'apple'}

将值添加到集合

fruits = {'apple', 'banana', 'grape'}
fruits.add('pear')
print(fruits)
# Prints: {'banana', 'grape', 'pear', 'apple'}

空集

因为{}语法会创建一个空词典,以创建一个空集,只需使用set()函数。

fruits = set()
fruits.add('pear')
print(fruits)
# Prints: {'pear'}

迭代集合中的值(不能保证订单)

fruits = {'apple', 'banana', 'grape'}
for fruit in fruits:
    print(fruit)
    # Prints:
    # banana
    # grape
    # apple

从集合中删除值

fruits = {'apple', 'banana', 'grape'}
fruits.remove('apple')
print(fruits)
# Prints: {'banana', 'grape'}

第10章:错误

如果您在课程中遇到了这么远,您可能会不时遇到代码中的一些错误。在Python中,有两种主要的可区分错误。

  • 语法错误
  • 例外

语法错误

您现在可能知道这些是什么。语法错误只是Python解释器告诉您,您的代码不遵守适当的Python语法。

this is not valid code, so it will error

如果我尝试像有效的代码一样运行该句子,我会得到语法错误:

this is not valid code, so it will error
      ^
SyntaxError: invalid syntax

例外

即使您的代码具有正确的语法,但在尝试执行它时仍可能导致错误。执行过程中检测到的错误称为“异常”,可以通过您的代码优雅处理。当您的代码中发生坏事时,您甚至可以提出自己的例外。

python使用一个试验模式来处理错误。

try:
  10 / 0
except Exception as e:
  print(e)

# prints "division by zero"

执行try块,直到提高例外或完成为止,以先到者为准。在这种情况下,由于不可能划分为零,因此会增加“零除以零”误差。仅当try块中提出异常时,仅执行except块。然后,它将异常视为数据(在我们的情况下为e),以便程序可以优雅地处理异常而不会崩溃。

提高自己的例外

错误是不是值得害怕的东西。预计在生产中运行的每个程序都将不断管理错误。我们作为开发人员的工作是优雅地处理错误,并以与用户的期望保持一致的方式。

错误不是错误

当我们自己的代码中发生某些事情时,我们应该提出自己的例外情况。例如,如果有人将一些不好的输入传递给我们写的函数,我们不应该害怕提出例外,让他们知道他们做错了什么。

error 异常在发生不良事件时会提高,但是只要我们的代码可以按照用户的期望处理,它是而不是 一个错误。一个错误是当代码以我们的用户不期望的方式行事时。

例如,如果玩家试图用青铜金属锻造铁剑,我们可能会提出异常并向玩家显示错误消息。但是,这就是游戏的预期行为,因此这不是错误。如果玩家可以从青铜中锻造铁剑,那可能被认为是一个错误,因为那是违反了游戏规则。

raise Exception("something bad happened")

软件应用程序并不完美,用户输入和网络连接远非可预测的。尽管进行了密集的调试和单元测试,但申请仍将发生故障案件。

网络连接的丢失,缺少数据库行,从内存问题出发以及意外的用户输入都可以防止应用程序“正常”执行。优雅地捕获和处理所有例外是您的工作,以便您的应用程序继续工作。当您能够检测到某件事是不对劲的时候,您应该自己提出错误,除了“默认”例外,Python解释器将升起。

raise Exception("something bad happened")

不同类型的异常

我们还没有涵盖类和对象,这就是Exception真正的核心。我们将在接下来为您排队的面向对象的编程课程中进行更多。

目前,重要的是要理解的是,有不同类型的异常,我们可以在代码中区分它们。

更多错误语法

try:
    10/0
except ZeroDivisionError:
    print("0 division")
except Exception:
    print("unknown exception")

try:
    nums = [0, 1]
    print(nums[2])
except ZeroDivisionError:
    print("0 division")
except Exception:
    print("unknown exception")

将要打印:

0 division
unknown exception

第11章:Python事实

Python的禅宗

蒂姆·彼得斯(Tim Peters),很长一段时间的毕达斯塔

美丽比丑陋更好。

显式比隐式更好。

简单胜于复杂。

复合物比复杂。

平坦比嵌套更好。

稀疏比密集好。

可读性计数。

特殊情况不足以违反规则。

尽管实用性击败了纯度。

错误永远不要静静地通过。

除非明确沉默。

面对歧义,拒绝猜测的诱惑。

应该有一种 - 最好只有一种 - 很明显的方法。

,尽管除非您是荷兰语,否则

一开始可能并不明显。

现在总比没有好。

虽然从来没有通常比右现在更好

如果实现很难解释,那是一个坏主意。

如果实现很容易解释,那可能是一个好主意。

名称空间是一个好主意 - 让我们做更多的事情!

为什么要python?

这是我们认为Python是开发人员的未来选择的一些原因:

  • 易于读写 - python读起来像普通英语。由于其简单的语法,这是实现AI等高级概念的绝佳选择。这可以说是Python的最佳功能
  • 流行 - 根据堆栈溢出开发人员调查,Python is the 4th most popular编码语言在2020年。
  • 免费 - 像如今的许多语言一样,Python是根据开源许可而开发的。它可以免费安装,使用和分发。
  • 便携式 - 为一个平台编写的Python将在任何其他平台上使用。
  • 解释 - 代码可以在编写后立即执行。因为不需要花费很长时间才能像Java,C ++或Rust这样的编译,所以将代码发布到生产中通常更快。

为什么不python?

python可能不是一个项目的最佳选择:

  • 代码需要快速运行。 Python代码执行非常缓慢,这就是为什么不使用Python编写PC Games(例如PC游戏)的性能。
  • 代码库将变得大而复杂。由于其动态类型系统,Python代码可能更难保持错误。
  • 该应用程序需要直接分发给非技术用户。他们将不得不安装Python才能运行您的代码,这将是巨大的不便。

Python 2 vs Python 3

继续您的Python旅程时要牢记的一件事是,Python生态系统患有分裂个性综合征。 Python 3于2008年12月3日发布,但是十年后,网络仍然充满了Python 2依赖项,脚本和教程。

在本课程中,我们使用了Python 3 - 就像如今任何好公民一样。

Python 2和3之间最明显的破坏变化之一是将文本打印到控制台的语法。

Python 2

print "hello world"

Python 3

print("hello world")

恭喜您到底!

如果您有兴趣完成本课程的交互式编码作业和测验,则可以查看Learn Python course over on Boot.dev

该课程是我完整的back-end developer career path的一部分,如果您有兴趣检查这些课程和项目,则由其他课程和项目组成。