Python是一门极易入手的解释型面向对象编程语言。由于之前的教程存在一些背书错误,也有小伙伴反映有些地方不容易理解。因此我决定重新编写一篇 Python 快速入门教学文章,这次的教学更加科学、易懂、全面。

学习代码的过程通常是先学它的基本的数据类型,然后从浅入深学习语法结构,最后再学习高级用法。此次快速入门教学会按照这个学习顺序让大家逐步学会 Python。

如果你不会甚至没有Python,你可以下载一个annaconda,根据它界面的提示一步步教你启用 Python 环境。跑代码的时候,只需要在 Pycharm 或者 VSCode 这样的编辑器里打开文件,然后按 F10 或者点击“三角形”运行按钮,就可以运行(跑)代码。

学习代码前,不妨试着跑一个最简单的显示“Hello, World!”的程序:

1
print("Hello, World!")

这个程序是一个print()函数表达式的语句。如果一切顺利,你会看到命令行窗口输出“Hello, World!”字样。

接下来,我们开始系统化快速入门 Python,大概需要6个小时。如有建议,可以通过邮件发送至taamyjipyjam@outlook.com,我会回复并视情况采纳。


一、学习 Python 数据类型

Python 的数据类型主要有两种:数字类型和组合类型。

1. 数字类型

Python 数字类型有四种:整数浮点数复数布尔值

数字能做什么呢?像加减乘除等运算、给某个变量赋值、大小判断都要用到数字。

数字类型不需要声明,通过它的表示方法可以自动识别,如:

整数:像12345678910这些,<纯数字>可以自动识别为十进制整数(其它进制的整数需要用0b0o0x表示)。

浮点数:像3.142.7181.618等,带有小数点.的数字可以自动识别为浮点数。

复数3+2j4-3j5+6j等,带有<虚数部分>的数字可以自动识别为复数。

布尔值:就是TrueFalse,各自表示真或假,其它数字转换为布尔值时,0为False,其它值为True

2. 组合类型

组合类型有三大类:序列映射集合。而序列由包括列表元组字符串range对象等。映射类型其实就是字典。集合类型则是由集合frozenset(不可变集合)等。

组合类型就像是容器,里面装着多个数字或其他数据,但组合类型数据它本身也是一种数据。也就是说,组合类型是由数字类型派生,且可以在 Python 直接使用的。

我们按照列表元组字符串range对象字典集合的顺序说明,组合类型也可以通过表示方法将其自动识别,如:

列表:用[]括起来的多个值,中间用,隔开,像[1, 2, 3, 4, 5]['apple', 'banana', 'orange'][1, 'apple', 3.14]这些。

元组:用()括起来的多个值,中间用,隔开。像(1, 2, 3, 4, 5)('apple', 'banana', 'orange')(1, 'apple', 3.14)这些。

字符串:用''""括起来的多个字符,内部无需分隔符,像'hello'""world""''""这些。

range对象:用range(<终止值>)range(<起始值>, <终止值>, <步长>)函数作为表达式生成的序列,像range(10)range(1, 10, 2)range(10, 0, -1)这些。其中range(10)表示0~9的整数序列,range(1, 10, 2)表示1~9的偶数序列,range(10, 0, -1)表示10~1的逆序序列。关于函数的详细说明在后面会提及。

字典:用{}括起来的键值对,中间用,隔开,键和值用:隔开,像{'name': 'Alice', 'age': 25}{'x': 1, 'y': 2, 'z': 3}这些。

集合:用{}括起来的多个值,中间用,隔开,但值不能重复,像{1, 2, 3, 4, 5}{'apple', 'banana', 'orange'}这些。

下面是 Python 数据类型的树形分类图。

你可以尝试把这些数据类型的实例,放进前面print(Hello, World!)例子中的print()函数括号内,看看输出结果。

二、学习 Python 语法结构

学习 Python 的语法结构,我们先拆解它的词法,然后看看这些拆解的部分(词素)是如何组合成语法结构的。

1. 词法分析

词法分析就是将代码分成多个词素(语法令牌)的过程。词素通过组合实现意义,被解释器解读。Python 有如下词素:标识符关键字运算符分隔符字面值注释

让我们看看这个例子:

1
print("Hello, World!")  # 后面这是注释

这行 Python 代码中,print是标识符,表示函数名;其后面的()""是分隔符,分别表示写入实参和写入字符串字面值;而Hello, World!是字符串字面值;#也是分隔符,后面写注释。

不同类型的词素有不同的作用:

  • 标识符:表示变量名、函数名、类名等。

  • 关键字:被解释器识别而产生不同的语义,如ifforwhiledefclass等。关键字不能作为标识符。

  • 运算符:运算符连接两个输入值,用来执行加减乘除等运算、比较等操作。就像1 + 1返回2(返回的意思是这串代码等效于某个值),2 > 1返回True

  • 分隔符:用来分隔词素,不包括运算符。其中,=也是分隔符,用来表示赋值操作。

  • 字面值:就像12.718TrueFalseNone"Hello, World!"(引号里面的)这些,字面值表示固定值,可以直接赋值给变量或作为参数传入函数。

  • 注释:以分隔符#开头,表示后面内容为注释,解释器会忽略掉。

2. 表达式

一个表达式会等效于返回一个值,可能存在副作用(改写某个内存地址指向的值)。表达式包括但不限于:

  • 标识符它本身,如变量名a
  • 字面值,如1
  • 含运算符的表达式,如1 + 2
  • 函数调用,如print("Hello, World!")
  • 序列索引,如列表索引a[0]
  • 三元运算符表达式,如a if b else c
  • 列表推导式,如[x**2 for x in range(10)]

其中,我们要留意以下比较特殊的表达式格式:

函数调用格式:

1
<函数名>(<实参列表>)  # 圆括号的实参列表作标识符后缀

序列索引格式:

1
<可变对象>[<索引表达式>]  # 方括号的索引表达式作标识符后缀

序列索引如列表a,它本身的值是[1, 2, 3],那么a[0]的值是1(从0开始从左往右数),如果索引是负值,如a[-1],那么它的值是3(从-1开始从右往左数)。

索引也可以通过切片,其中索引表达式格式为[<起始索引>:<终止索引>:<步长>],如a[1:3:2]表示从索引1到3(不包括3)的步长为2的切片。

三元运算符格式:

1
<表达式1> if <条件表达式> else <表达式2>

列表推导式格式:

1
[<表达式> for <变量> in <可迭代对象> if <条件表达式>]

验证表达式的计算结果,我们可以使用print()函数进行打印输出查看。

当我们认识了表达式,我们就可以理解语句,把语句拆解为几个部分(不至于细分至词素),然后再把这些部分组合成语法结构。我们可以忽略注释,将标识符、字面值、运算符、部分分隔符、部分关键字(这些关键字充当运算符的作用)等词素组合成表达式。于是,我们就能把语句拆成这三部分:表达式关键字分隔符

3. 表达式语句

格式:

1
<表达式>

大多数情况下,表达式语句用于函数调用、三元运算或列表推导式。

4. 赋值语句

格式:

1
<可变对象组,如变量名> = <表达式组>

“组”表示多值用逗号隔开。

= 右侧的表达式赋值给左侧的可变对象。

当一行并列多个=时,依次从右往左赋值。

= 可替换为其他赋值符号,如 += 表示自增赋值。

例:

1
2
3
4
5
6
a = 1  # 1赋值给变量a
b, c = a, 2 # a的值赋值给b,2赋值给c
d = [1, 2, 3] # 列表[1, 2, 3]赋值给d
d[0] = 4 # d[0]的值由1变为4
c += 1 # c的值由2变为3
a = b = c # a、b、c的值都变为3

5. 控制结构

控制结构需要用到控制结构语句,包括

  • 条件判断:if语句、match语句

  • 循环结构:for语句、while语句

  • 异常处理:try语句、raise语句

控制结构视情况使用相关的跳转语句,如continue语句、break语句。

1. if 语句

格式:

1
2
3
4
5
6
if <条件表达式>:
<语句组1>
elif <条件表达式>:
<语句组2>
else:
<语句组3>
  1. 条件表达式:布尔值表达式,如果为True,则执行语句组1,否则,如果有elif子句,则判断下一个条件表达式,如果为True,则执行对应的语句组,否则,如果有else子句,则执行语句组3。

  2. 语句组:可以是单个语句,也可以是多条语句组成的复合语句。

例如:

1
2
3
4
5
6
7
a = 1
if a == 1:
print("a is 1")
elif a == 2:
print("a is 2")
else:
print("a is not 1 or 2")

此时,如果a的值为1,则输出a is 1,如果a的值为2,则输出a is 2,否则,输出a is not 1 or 2。实际上,这里的输出结果为a is 1

2. match 语句

格式:

1
2
3
4
5
6
7
8
9
10
11
12
13
match <表达式>:
case <匹配表达式1>:
<语句组1>
case <匹配表达式2>:
<语句组2>
case <匹配表达式3>:
<语句组3>
...
case <匹配表达式n>:
<语句组n>
...
case _:
<默认语句组>

match表达式的值与case子句的匹配表达式相匹配时(即两者相等),则执行对应的语句组。如果没有匹配成功,则执行默认语句组。

例子:

1
2
3
4
5
6
7
8
a = 2
match a:
case 1:
print("a is 1")
case 2:
print("a is 2")
case _:
print("a is not 1 or 2")

此时,如果a的值为1,则输出a is 1,如果a的值为2,则输出a is 2,否则,输出a is not 1 or 2。实际上,这里的输出结果为a is 2

3. for 语句

格式:

1
2
for <变量> in <可迭代对象>:
<语句组>

for语句用于遍历可迭代对象,每次迭代,变量的值会被设置为可迭代对象的下一个元素。

当语句组有语句使用跳转语句break时,for语句会立即结束;如果使用continue语句,则会跳过当前迭代,继续下一次迭代。

例如:

1
2
3
4
for i in range(1, 10):
if i % 2 == 0:
continue
print(i)

此时,for语句会遍历range(1, 10),每次迭代,i的值会被设置为range(1, 10)的下一个元素,如果i是偶数,则continue语句会跳过当前迭代,继续下一次迭代。如果i是奇数,则print(i)语句会输出i

4. while 语句

格式:

1
2
while <条件表达式>:
<语句组>

如果条件表达式为True,则执行语句组,否则,继续循环。

当语句组有语句使用跳转语句break时,while语句会立即结束;如果使用continue语句,则会跳过当前循环,继续下一次循环。

例如:

1
2
3
4
5
6
i = 0
while i < 5:
i += 1
if i == 3:
continue
print(i)

此时,while语句会一直循环,直到i的值大于等于5。如果i的值是3,则continue语句会跳过当前循环,继续下一次循环。如果i的值是奇数,则print(i)语句会输出i

5. try 语句

格式:

1
2
3
4
5
6
7
8
9
10
11
12
13
try:
<语句组1>
except <异常类型1>:
<语句组2>
except <异常类型2>:
<语句组3>
...
except <异常类型n>:
<语句组n>
else:
<语句组n+1>
finally:
<语句组n+2>

try语句用于捕获异常,如果语句组1执行过程中发生异常,则依次匹配异常类型,如果匹配成功,则执行对应的语句组2、3、…,如果没有匹配成功,则执行else语句组。如果语句组1执行完成,没有发生异常,则执行finally语句组。

例如:

1
2
3
4
5
6
7
8
try:
a = 1 / 0
except ZeroDivisionError:
print("division by zero!")
else:
print("no exception occurred")
finally:
print("clean up")

此时,try语句会尝试执行a = 1 / 0,由于0不能作为除数,所以会抛出ZeroDivisionError异常,except语句会捕获到这个异常,并执行print("division by zero!")语句。由于没有else语句,所以no exception occurred不会被打印。finally语句会在try语句执行完成后执行,即clean up会被打印。

6. raise 语句

格式:

1
raise <异常类型>(<异常消息>)

raise语句用于抛出异常,并附带异常消息。

例如:

1
raise ValueError("invalid input")

此时,raise语句会抛出一个ValueError异常,并附带异常消息invalid input

6. 函数定义及调用

函数定义需要用到函数定义语句,格式:

1
2
def <函数名>(<参数列表>):
<语句组>

函数调用使用函数调用表达式的表达式语句,格式:

1
<函数名>(<实参列表>)

当函数定义语句中的语句组使用跳转语句return时,函数调用者会收到函数的返回值。如果没有return语句,则函数调用者会收到None

def语句用于定义函数,函数名后面是参数列表,参数列表以逗号隔开,每个参数由变量名和类型组成,类型可以省略。

例如:

1
2
3
4
def my_function(a, b):
return a + b

result = my_function(1, 2) # 返回 3

7. 面向对象

面向对象通过定义类(一个抽象拥有属性和方法),然后将其实例化为对象,通过给对象调用方法来实现对对象的操作(改它的属性并执行副作用)。

1. 定义类

定义类需要用到类定义语句,格式:

1
2
3
class <类名>:
<属性定义>
<方法定义>

类名后面是属性定义和方法定义,属性定义以self.属性名 = 初始值的形式定义,方法定义以def 方法名(self, 参数列表):的形式定义。通常我们会定义一个__init__方法,用于初始化对象。

例如:

1
2
3
4
5
6
7
class Person:
def __init__(self, name, age):
self.name = name
self.age = age

def say_hello(self):
print("Hello, my name is " + self.name)

此时,我们定义了一个Person类,它有两个属性nameage,有一个实例方法__init__,用于实例化对象,还有一个say_hello方法,用于打印出对象的名字。

2. 实例化

实例化就是通过赋值语句将类实例化为对象,格式:

1
<对象名> = <类名>(<实参列表>)

继续刚才的例子:

1
person1 = Person("Ben", 26)

此时,我们实例化了一个Person类,并将其赋值给person1变量,person1变量是一个Person类的对象,它有name属性为"Ben"age属性为26

3. 调用方法

方法通过方法调用表达式的表达式语句来调用,格式:

1
<对象>.<方法名>(<实参列表>)

依然继续刚才的例子:

1
person1.say_hello()  # 输出 "Hello, my name is Ben"

此时,我们调用了person1对象的say_hello方法,它会打印出对象的名字。

8. 模块导入

模块导入使用importfrom-import语句,格式:

1
2
import <模块名>
from <模块名> import <标识符1>, <标识符2>, ...
  1. import语句用于导入整个模块,将模块中的所有标识符导入当前命名空间。

  2. from-import语句用于导入模块中的指定标识符,将指定的标识符导入当前命名空间。

例如:

1
2
3
4
5
6
import math
from math import pi, sin, cos

print(math.pi) # 输出 3.141592653589793
print(sin(math.pi/2)) # 输出 1.0
print(cos(math.pi/2)) # 输出 6.123233995736766e-17

此时,我们导入了math模块,并将其中的pisincos标识符导入当前命名空间。我们调用了math模块的pisincos函数,并打印了结果。

9. 文件读写(with 语法糖)

with语法糖用于简化上下文管理器(context manager)的使用,格式:

1
2
with <上下文管理器> as <变量>:
<语句组>

上下文管理器是一个实现了__enter____exit__方法的对象,__enter__方法用于进入上下文,__exit__方法用于退出上下文,进行文件读写、打开和关闭,并处理异常。

语法糖表示代码的简化,它等效于某种更复杂的代码。

这个语法糖等效于:

1
2
3
4
5
6
7
<变量> = <上下文管理器>.__enter__()
try:
<语句组>
except:
<上下文管理器>.__exit__(*sys.exc_info())
else:
<上下文管理器>.__exit__(None, None, None)

例如:

1
2
3
with open("file.txt", "r") as f:
data = f.read()
print(data)

此时,with语句会打开文件file.txt,将其内容赋值给f变量,并执行f.read()语句,打印出文件内容。

最后,关于 Python 语法结构的分类,我们可以列出如下树形结构图:


以上就是本人整理的 Python 快速入门教程,以后会更新高级用法,希望对你有所帮助。