Python快速入门(新版)
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 数字类型有四种:整数、浮点数、复数、布尔值。
数字能做什么呢?像加减乘除等运算、给某个变量赋值、大小判断都要用到数字。
数字类型不需要声明,通过它的表示方法可以自动识别,如:
整数:像1
、2
、3
、4
、5
、6
、7
、8
、9
、10
这些,<纯数字>
可以自动识别为十进制整数(其它进制的整数需要用0b
或0o
或0x
表示)。
浮点数:像3.14
、2.718
、1.618
等,带有小数点.
的数字可以自动识别为浮点数。
复数:3+2j
、4-3j
、5+6j
等,带有<虚数部分>
的数字可以自动识别为复数。
布尔值:就是True
或False
,各自表示真或假,其它数字转换为布尔值时,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 数据类型的树形分类图。
graph TD Root(Python 数据类型) Root --> A(数字类型) Root --> B(组合类型) A --> A1(整数) --> A1a(<纯数字>) A --> A2(浮点数) --> A2a(<小数点>) A --> A3(复数) --> A3a(<虚数部分>) A --> A4(布尔值) --> A4a(True/False) B --> B1(序列类型) B --> B2(映射类型) B --> B3(集合类型) B1 --> B1a(列表) --> B1a1("[]") B1 --> B1b(元组) --> B1b1("()") B1 --> B1c(字符串) --> B1c1(<引号>) B1 --> B1d(range对象) --> B1d1("range()") B2 --> B2a(字典) --> B2a1("{<key>:<value>}") B3 --> B3a(集合) --> B3a1("{}") B3 --> B3b(frozenset) --> B3b1("frozenset()")
你可以尝试把这些数据类型的实例,放进前面print(Hello, World!)
例子中的print()
函数括号内,看看输出结果。
二、学习 Python 语法结构
学习 Python 的语法结构,我们先拆解它的词法,然后看看这些拆解的部分(词素)是如何组合成语法结构的。
1. 词法分析
词法分析就是将代码分成多个词素(语法令牌)的过程。词素通过组合实现意义,被解释器解读。Python 有如下词素:标识符、关键字、运算符、分隔符、字面值、注释。
让我们看看这个例子:
1 | print("Hello, World!") # 后面这是注释 |
这行 Python 代码中,print
是标识符,表示函数名;其后面的()
和""
是分隔符,分别表示写入实参和写入字符串字面值;而Hello, World!
是字符串字面值;#
也是分隔符,后面写注释。
不同类型的词素有不同的作用:
标识符:表示变量名、函数名、类名等。
关键字:被解释器识别而产生不同的语义,如
if
、for
、while
、def
、class
等。关键字不能作为标识符。运算符:运算符连接两个输入值,用来执行加减乘除等运算、比较等操作。就像
1 + 1
返回2
(返回的意思是这串代码等效于某个值),2 > 1
返回True
。分隔符:用来分隔词素,不包括运算符。其中,
=
也是分隔符,用来表示赋值操作。字面值:就像
1
、2.718
、True
、False
、None
、"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 | a = 1 # 1赋值给变量a |
5. 控制结构
控制结构需要用到控制结构语句,包括
条件判断:
if
语句、match
语句循环结构:
for
语句、while
语句异常处理:
try
语句、raise
语句
控制结构视情况使用相关的跳转语句,如continue
语句、break
语句。
1. if 语句
格式:
1 | if <条件表达式>: |
条件表达式:布尔值表达式,如果为
True
,则执行语句组1,否则,如果有elif
子句,则判断下一个条件表达式,如果为True
,则执行对应的语句组,否则,如果有else
子句,则执行语句组3。语句组:可以是单个语句,也可以是多条语句组成的复合语句。
例如:
1 | a = 1 |
此时,如果a
的值为1
,则输出a is 1
,如果a
的值为2
,则输出a is 2
,否则,输出a is not 1 or 2
。实际上,这里的输出结果为a is 1
。
2. match 语句
格式:
1 | match <表达式>: |
当match
表达式的值与case
子句的匹配表达式相匹配时(即两者相等),则执行对应的语句组。如果没有匹配成功,则执行默认语句组。
例子:
1 | a = 2 |
此时,如果a
的值为1
,则输出a is 1
,如果a
的值为2
,则输出a is 2
,否则,输出a is not 1 or 2
。实际上,这里的输出结果为a is 2
。
3. for 语句
格式:
1 | for <变量> in <可迭代对象>: |
for
语句用于遍历可迭代对象,每次迭代,变量的值会被设置为可迭代对象的下一个元素。
当语句组有语句使用跳转语句break
时,for
语句会立即结束;如果使用continue
语句,则会跳过当前迭代,继续下一次迭代。
例如:
1 | for i in range(1, 10): |
此时,for
语句会遍历range(1, 10)
,每次迭代,i
的值会被设置为range(1, 10)
的下一个元素,如果i
是偶数,则continue
语句会跳过当前迭代,继续下一次迭代。如果i
是奇数,则print(i)
语句会输出i
。
4. while 语句
格式:
1 | while <条件表达式>: |
如果条件表达式为True
,则执行语句组,否则,继续循环。
当语句组有语句使用跳转语句break
时,while
语句会立即结束;如果使用continue
语句,则会跳过当前循环,继续下一次循环。
例如:
1 | i = 0 |
此时,while
语句会一直循环,直到i
的值大于等于5。如果i
的值是3
,则continue
语句会跳过当前循环,继续下一次循环。如果i
的值是奇数,则print(i)
语句会输出i
。
5. try 语句
格式:
1 | try: |
try
语句用于捕获异常,如果语句组1执行过程中发生异常,则依次匹配异常类型,如果匹配成功,则执行对应的语句组2、3、…,如果没有匹配成功,则执行else
语句组。如果语句组1执行完成,没有发生异常,则执行finally
语句组。
例如:
1 | try: |
此时,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 | def <函数名>(<参数列表>): |
函数调用使用函数调用表达式的表达式语句,格式:
1 | <函数名>(<实参列表>) |
当函数定义语句中的语句组使用跳转语句return
时,函数调用者会收到函数的返回值。如果没有return
语句,则函数调用者会收到None
。
def
语句用于定义函数,函数名后面是参数列表,参数列表以逗号隔开,每个参数由变量名和类型组成,类型可以省略。
例如:
1 | def my_function(a, b): |
7. 面向对象
面向对象通过定义类(一个抽象拥有属性和方法),然后将其实例化为对象,通过给对象调用方法来实现对对象的操作(改它的属性并执行副作用)。
1. 定义类
定义类需要用到类定义语句,格式:
1 | class <类名>: |
类名后面是属性定义和方法定义,属性定义以self.属性名 = 初始值
的形式定义,方法定义以def 方法名(self, 参数列表):
的形式定义。通常我们会定义一个__init__
方法,用于初始化对象。
例如:
1 | class Person: |
此时,我们定义了一个Person
类,它有两个属性name
和age
,有一个实例方法__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. 模块导入
模块导入使用import
或from-import
语句,格式:
1 | import <模块名> |
import
语句用于导入整个模块,将模块中的所有标识符导入当前命名空间。from-import
语句用于导入模块中的指定标识符,将指定的标识符导入当前命名空间。
例如:
1 | import math |
此时,我们导入了math
模块,并将其中的pi
、sin
和cos
标识符导入当前命名空间。我们调用了math
模块的pi
、sin
和cos
函数,并打印了结果。
9. 文件读写(with 语法糖)
with
语法糖用于简化上下文管理器(context manager)的使用,格式:
1 | with <上下文管理器> as <变量>: |
上下文管理器是一个实现了__enter__
和__exit__
方法的对象,__enter__
方法用于进入上下文,__exit__
方法用于退出上下文,进行文件读写、打开和关闭,并处理异常。
语法糖表示代码的简化,它等效于某种更复杂的代码。
这个语法糖等效于:
1 | <变量> = <上下文管理器>.__enter__() |
例如:
1 | with open("file.txt", "r") as f: |
此时,with
语句会打开文件file.txt
,将其内容赋值给f
变量,并执行f.read()
语句,打印出文件内容。
最后,关于 Python 语法结构的分类,我们可以列出如下树形结构图:
graph TD Root(Python 语法结构) Root --> A(表达式语句) Root --> B(赋值语句) Root --> C(控制结构) Root --> D(函数定义) Root --> E(面向对象) A --> A1(函数/方法调用) --> A1a("函数/方法名()") A --> A2(三元运算) --> A2a(if-else) A --> A3(列表推导式) --> A3a(for-in-if) B --> B1(直接赋值) --> B1a(=) B --> B2(增量赋值) --> B2a(+=) B --> B3(多值赋值) --> B3a(a,b=c,d) C --> C1(条件判断) C --> C2(循环结构) C --> C3(异常处理) C1 --> C1a(if) C1 --> C1b(match) C2 --> C2a(for) C2 --> C2b(while) C3 --> C3a(try) C3 --> C3b(raise) D --> D1(def) E --> E1(类定义) E1 --> E1a(class) C2a --> G1(break) C2b --> G1 C2a --> G2(continue) C2b --> G2 D1 --> G3(return) G1 --> G4(跳转语句) G2 --> G4 G3 --> G4 Root --> F(模块导入) F --> F1(import) F --> F2(from-import) Root --> H(文件读写) H --> H1(with)
以上就是本人整理的 Python 快速入门教程,以后会更新高级用法,希望对你有所帮助。