跳转至

第2章 Python编程基础

2.1 变量与表达式

2.1.1 变量的定义与赋值

变量定义

  • 变量名
  • 以字母或下划线开头,由字母、数字或下划线组成
  • 不能以Python关键字作为变量名
  • 不要使用特殊变量名(以__)开始和结尾
1
2
y = 1
y
1
1
1
__name__
1
'__main__'
  • 动态类型
  • 在变量定义时无需指定变量的类型
  • 同一个变量可以被赋予完全不同类型的取值
1
2
3
4
5
6
x = 1
print(type(x))
x = 1.1
print(type(x))
x = 'abc' 
print(type(x))
1
2
3
<class 'int'>
<class 'float'>
<class 'str'>
  • 类型注解(Type Hint)
  • 非强制性
1
2
3
x: int = 1
x: float = 1.1
x: str = 'python'

变量赋值

1
2
3
x = y = z = 1
x, y, z = 1, 2, 3
x, y = y, x  # 交换数值 
1
True

2.1.2 算术表达式

算术运算符

运算符 功能 增强运算符
+ +=
- -=
* *=
/ /=
** 乘方 **=
// 整除 //=
% 求余 %=
1
2
3
x = 1
x = x % 2
x 
1
1
1
3 + 4 * 5
1
23
1
10 / 3
1
3.3333333333333335
1
10 // 3
1
3
1
10 % 3
1
1

2.1.3 关系表达式与逻辑表达式

关系运算符

运算符 功能
> 大于
< 小于
>= 大于等于
<= 小于等于
== 逻辑相等
!= 不等于

逻辑运算符

运算符 功能
and 逻辑与
or 逻辑或
not 逻辑非
is 判断两个对象是否相同
is not 判断两个对象是否不相同
in 判断一个对象是否在一个容器对象中
not in 判断一个对象是否不在一个容器对象中
1
x, y = 1, 2
1
x == 1
1
True
1
x == 1 and y == 2
1
True
1
x < y < 0 
1
False

2.1.4 海象运算符

  • Python 3.8中加入了一种新的运算符:=,称为海象运算符
  • 能够在计算逻辑表达式的同时,将表达式的一部分赋值给一个变量
1
(x:=1) > (y:=2)
1
False
1
x
1
1
1
y
1
2
  • 相当于:
1
2
3
x = 1
y = 2
x > y
1
False

2.1.5 运算符的优先级

  • 逻辑运算符 > 比较运算 > 算术运算符
  • 合理使用()
1
2
l = [9, 5, 2, 7]
(2 in l) and (6 > (len(l) + 1) >= 4)
1
True

2.2 语句

2.2.1 简单语句

  • 表达式
  • 输出语句
1
print("Hello Python!")
1
Hello Python!
1
2
x, y = 1, 2
print("x=", x, ", y=", y, 'abc')
1
x= 1 , y= 2 abc
  • 输入语句
1
2
3
s = input("请输入数据:")
print(s)
print(type(s))
1
2
3
请输入数据:1
1
<class 'str'>
  • 函数调用
  • 删除对象
1
2
3
x = 10
del x
x
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
---------------------------------------------------------------------------

NameError                                 Traceback (most recent call last)

<ipython-input-8-3dde88e24a37> in <module>
      1 x = 10
      2 del x
----> 3 x


NameError: name 'x' is not defined
  • 导入模块
1
2
3
import math
math.pi
math.sin(math.pi)
1
1.2246467991473532e-16

2.2.2 复合语句与空语句

  • 复合语句(语句块)
  • C/C++、C#、Java中使用{}
  • VB中使用begin ... end
  • Python使用代码的缩进来标识出一个语句块
    • 连续多条具有相同缩进的语句,会被解释器判断为隶属于一个语句块
    • 代码的缩进是强制性的
1
2
3
4
5
if True:
    print('Hello')
    print('Python') 
    if True:
        pass
1
2
Hello
Python
  • 语句换行
  • 过长的语句也会影响代码的可读性
1
2
5 > 3 and \
1 < 2
1
True
1
2
5 > 3 and (
    1 < 2)
1
True
  • 空语句
  • pass
  • 用于标识出空语句块
1
2
if True:
    pass

### 2.2.3 注释

  • 单行注释
  • #
  • 多行注释
  • '''
  • """
  • 特殊注释
  • #!/usr/bin/python#!/usr/bin/env/python或其他解释器所在路径
  • # -*- coding: utf-8 -*-# coding=utf-8

2.3 数据类型

2.3.1 基本数据类型

Python基本数据类型

类型 表示符 示例
字符 str 'Hello Python'
数值 int, float, complex 1, 1.0, 1+2j
序列 list, tuple [1, 2, 3], (1, 2, 3)
字典 dict {'x': 1, 'y': 2}
集合 set, frozenset {1, 2, 3}
布尔 bool True, False
  • 字符类型
  • 'Hello Python'
  • "Hello Python"
  • '''Hello Python'''
  • """Hello Python"""
1
2
3
4
5
6
7
s = "Hello' Python"
s = 'Hello" Python'
s = '''
   Hello
   Python
'''
print(s)
1
2
   Hello
   Python

  • 特殊字符串
  • r'Hello Python'
  • u'Hello Python'
  • b'Hello Python!'
  • f'Hello Python'

  • 数值类型

  • int
  • float
  • complex
1
2
3
1j ** 2
c = complex(1 + 2j)
type(c)
  • 序列类型
  • list:列表,可变类型
  • tuple:元组,不可变类型
1
2
3
4
l = [9, 5, 2, 7, 'abc']
l[0] = 6  # 索引
print(l[0:2])    # 切片
type(l)
1
2
3
4
5
6
7
[6, 5]





list
1
2
3
4
t = (9, 5, 2, 7)
print(t[0])
print(t[0:2])
t[0] = 6
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
9
(9, 5)



---------------------------------------------------------------------------

TypeError                                 Traceback (most recent call last)

<ipython-input-15-ed2d24a5a67e> in <module>
      2 print(t[0])
      3 print(t[0:2])
----> 4 t[0] = 6


TypeError: 'tuple' object does not support item assignment
  • 序列解包
1
2
3
x, y, z = 9, 5, 2
x, y, *z = (9, 5, 2, 7)
z
1
[2, 7]
  • 临时变量_
1
x, *_ = (9, 5, 2)
  • 集合类型
  • 元素无序
  • 集合运算
1
2
3
4
5
6
7
8
9
s1 = {9, 5, 2}
s2 = {5, 2, 7}
print(s1 | s2)
print(s1 & s2)

l = [1, 1, 2, 2, 3, 3]
s = set(l)
print(type(l), type(s))
print(s)
1
2
3
4
{2, 5, 7, 9}
{2, 5}
<class 'list'> <class 'set'>
{1, 2, 3}
  • 字典类型
  • 元素由key-value对组成
  • 使用key访问元素的值
1
2
3
4
5
6
d = {'x': 1, 'y': 2}
d['z'] = 3
print(d)

l = dict()
print(type(l))
1
2
{'x': 1, 'y': 2, 'z': 3}
<class 'dict'>
  • 布尔类型
  • 取值为TrueFalse

2.3.2 空类型

  • None
  • 判断一个变量的取值是否为空要使用isis not关键字
1
2
3
4
x = None
print(x is None)
print(x is not None)
type(x)
1
2
3
4
5
6
7
8
True
False





NoneType

2.3.3 扩展数据类型

  • 函数
1
2
3
4
5
def fun():
    pass
print(fun.__name__)
fun.__name__ = 'test'
print(fun.__name__)
1
2
fun
test
1
2
3
4
5
6
7
8
class Human:
    name = ''
    def say(self):
        print('My name is', self.name)
    def run(self):
        self.say()

Human.__name__  # 注意__name__与name是不同的属性
1
'Human'
  • 对象(实例)
1
2
3
h = Human()
h.name = '张三'
h.say()
1
My name is 张三
  • 模块
1
2
import math
math.__name__
1
'math'

2.4 流程控制

2.4.1 结构化程序设计

  • GOTO语句
  • 结构化程序设计是一种编程范式或编程思维,最早由荷兰计算机科学家Edsger Dijkstra提出
  • 核心的特征
  • 将软件代码划分为子程序(函数或方法)、代码块等模块,再通过流程控制将各模块连接起来
  • 作用
  • 程序具有清晰的逻辑结构
  • 提高软件质量
  • 降低软件的维护成本

  • 三种基本的流程控制结构

  • 顺序结构
  • 选择结构
  • 循环结构

2.4.2 选择

  • 语法
1
2
3
4
5
6
7
8
9
if 逻辑表达式1:
    语句块1
elif 逻辑表达式2:
    语句块2
elif 逻辑表达式3:
    语句块3
...
else:
    语句块
1
2
3
4
5
6
7
x = int(input("请输入一个整数:"))
if x < 0:
    print("您输入了一个负数!")
elif x == 0:
    print("您输入了零!")
else:
    print("您输入了一个正数!")
1
2
请输入一个整数:0
您输入了零!
  • 海象运算符的使用
1
2
3
s = 'Python is interesting!'
if (s_len:=len(s)) > 10:
    print("字符串长度为", s_len, '超出了最大长度!')
1
字符串长度为 22 超出了最大长度!
  • 若不使用海象运算法,则需要运算两次len
1
2
3
s = 'Python is interesting!'
if len(s) > 10:
    print("字符串长度为", len(s), '超出了最大长度!')
1
字符串长度为 22 超出了最大长度!
  • if..else表达式
  • 相当于C/C++语言中的三目运算符
  • if 逻辑表达式 else ...
1
2
3
4
x = int(input("请输入一个整数:"))
is_positive = True if x > 0 else False
is_positive
True
1
2
3
4
5
6
7
请输入一个整数:10





True

2.4.3 循环

for循环

  • 遍历可迭代对象
  • 语法
    1
    2
    for 变量 in 可迭代对象:
      语句块
    
1
2
3
4
5
6
l = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
sum_l = 0
for n in l:
    sum_l += n
#     sum_l = sum_l + n
print(sum_l)
1
2
3
4
5
6
7
45





45
  • range函数
  • range(n):返回一个最小值为0,最大值为n-1的range对象;
  • range(m, n):返回一个最小值为m,最大值为n-1的range对象;
  • range(m, n, s):返回一个最小值为m,最大值为n-1,步长为s的range对象。
1
2
3
4
sum_l = 0
for n in range(10):
    sum_l += n
print(sum_l)
1
45
1
2
3
4
5
6
# 求大于等于1且小于100的奇数之和
sum_odd = 0
for n in range(1, 100, 2):
    sum_odd += n
print(sum_odd)
sum(range(1, 100, 2))
1
2
3
4
5
6
7
2500





2500
  • enumerate函数
  • enumerate函数能够将一个可迭代对象转换成enumerate对象
  • 每个元素都是一个形如(索引, 值)的元组
1
2
3
text = 'Python'
for i, s in enumerate(text):
    print(text, '的第', i+1, '个字母是', s)
1
2
3
4
5
6
Python 的第 1 个字母是 P
Python 的第 2 个字母是 y
Python 的第 3 个字母是 t
Python 的第 4 个字母是 h
Python 的第 5 个字母是 o
Python 的第 6 个字母是 n
  • zip函数
  • 像拉链一样将两个序列“咬合”起来
  • 接受两个或多个序列对象,返回一个可迭代的zip对象
1
2
3
4
names = ['张三', '李四', '王五']
scores = [95, 59, 80]
for name, score in zip(names, scores):
    print(name, "的分数是", score)
1
2
3
张三 的分数是 95
李四 的分数是 59
王五 的分数是 80

while循环

  • 语法
    1
    2
    while 条件表达式:
      语句块
    
  • 语句块中必须有改变条件表达式的语句或者退出循环的语句
1
2
3
4
5
6
sum_value = 0
i = 0
while i < 10:
    sum_value += i
    i += 1          # 不要忘记改变循环条件
print(sum_value)

breakcontinue

  • break
  • 提前终止循环
  • continue
  • 中止当前的迭代,提前进入到下一轮迭代
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
# 输出20以内所有能被3整除的数
i = 0
while True:
    if i >= 20:
        break
    i += 1
    if i % 3 != 0:
        continue
    print(i)
pass
1
2
3
4
5
6
3
6
9
12
15
18

else子句

  • for循环和while循环都有一个else子句

  • for

    1
    2
    3
    4
    for 变量 in 可迭代对象:
        语句块
    else:
        语句块
    

  • while

    1
    2
    3
    4
    while 条件表达式:
        语句块
    else:
        语句块
    
    - else子句中的语句块,只有循环完整执行完毕时才执行。若使用了break语句提前退出循环,则else子句中的语句块不会被执行

2.5 模块与包

2.5.1 模块和包的导入

1
2
3
4
5
6
import math               # 方法1:导入模块
print(math.sin(0.5 * math.pi))
import math as m          # 方法2:导入模块并为其取别名
print(m.sin(0.5 * m.pi))
from math import pi, sin  # 方法3:导入模块中的函数
print(sin(0.5 * pi)) 
1
2
3
1.0
1.0
1.0

2.5.2 自定义包*

  • Python中的包与普通文件夹的区别在于,作为包的文件夹中包含一个名为__init__.py的特殊文件
  • 相对导入
  • .表示当前包,..表示当前包的父包,...表示父包的父包

例:一个名为project的项目

1
2
3
4
5
6
7
8
project
├── A
│   ├── B
│   │   ├── __init__.py
│   │   └── module_in_B.py
│   ├── __init__.py
│   └── module_in_A.py
└── module.py
  • module.py中导入变量ab
1
2
from A.module_in_A import a
from A.B.module_in_B import b
  • module_in_A.py中导入变量b
1
from .B.module_in_B import b
  • module_in_B.py中导入变量a
1
from ..module_in_A import a
  • 导入包时的查找顺序
  • 查看被导入的是否是内置模块
  • sys.path中的路径
  • 若搜索不到就返回导入错误
  • sys.path
    1
    2
    import sys
    sys.path.append('package_path')
    

2.5.3 常用内置模块*

模块 简介
time 日期时间处理模块,包含了常用的日期时间计算与格式化处理的函数。
datatime 对time模块进行了封装,包含了常用的关于日期时间的类。
random 包含了常用的随机数生成函数。
sys 包含了访问与控制Python解释器的变量和函数。
os 包含了对操作系统进行操作的函数。
collections 包含了更丰富的容器类。
itertools 包含了操作可迭代对象的非常有用的函数。
functools 包含了关于函数式编程的相关功能函数。
json 解析与处理JSON格式数据的工具集合。
XML 解析与处理XML格式数据的模块。
pickle 序列化模块,用于将Python对象存储在磁盘之中。
re 正则表达式模块。
logging 日志处理模块。
urllib 用于HTTP请求、操作URL的模块。
HTMLParser 用于解析HTML文档的模块。
threading 用于多线程编程的模块。
subprocess 利用Python运行其他程序,只要是在命令行里能够执行的命令,都可以利用模块在Python中运行。
multiprocessing 多进程编程模块。

2.6 Python编程规范

2.6.1 规范编码的重要性

  • 团队合作的需要。软件开发往往是一项团队工作,如果不遵循相同的代码规范,团队合作难以进行;
  • 规范性良好的代码有利用避免程序错误;
  • 规范性良好的代码能够有效降低维护成本。

2.6.2 PEP8规范(Python Enhancement Proposal)

代码布局

  • 缩进
  • 使用4个空格的缩进方式
  • 不使用Tab,更加不能混合使用空格和Tab
  • 每行代码长度

  • 每行代码长度79个字符

  • 在运算符之前断行
  • 空行
  • 顶层函数和类前空2行
  • 类内方法前空1行
  • 逻辑代码块之间空1行
  • 导入
  • 导入语句位于脚本的顶部
  • 每个import语句仅导入一个模块
  • 可使用from ... import导入同一模块中的多个对象

表达式和语句中的空格

  • 避免使用多余的空格
  • ()[]{}内部相邻的位置不要有空格
  • ,:;之前不要有空格,之后要有一个空格
  • :作为切片符号时,前后都不要有空格
  • 行尾不要有空格
  • 函数参数中的运符算前后不要有空格

  • 使用空格的情况

  • 二元运算符,例如===>等,前后要有一个空格(函数参数列表除外)

文档与注释

  • 与代码相矛盾的注释不如无注释,修改代码时应当先修改其注释
  • 建议将注释放在位置于代码之前的注释块之中
  • 谨慎使用行尾注释,若要使用则#之前至少有两个空格,之后一个空格
  • 所有公共模块、函数、类和方法都应当有文档字符串

标识符的命名

  • 避免使用的命名
  • l(小写的L)、O(字母O)、I(大写字母i)
  • 无意义的字符串
  • 包含非ASCII符号的命名
  • 变量或对象名
  • 所有字母小写,可用下划线分隔多个词
  • 模块名和包名
  • 模块名和包名都应当简短,所有字母小写
  • 模块名可包含下划线提高可读性,包名中不要包含下划线
  • 类名
  • 首字母大写
  • 函数与方法
  • 函数名与方法名仅包含小写字母,可用下划线分隔多个词
  • 非公开的方法前添加一个下划线
  • 常量
  • 所有字母大写,可用下划线分隔多个词