一、输出函数及转义字符

输出函数

和java一样,使用print函数控制输出,输出字符串示例:

1
print("hello world")
1
hello world

也可以输出含有运算符的表达式,会直接打印表达式结果:

1
print(3 + 2)
1
5

转义字符

反斜杠+想要实现的转义功能首字母既为转义字符
当字符串中包含反斜杠、单引号、双引号时等有特殊作用的字符时,必须使用反斜杠对这些字符进行转义:

1
2
3
反斜杠:\\
单引号:\'
双引号:\"

当字符串中包含换行、回车、水平制表符或退格等无法直接表示的特殊字符时,也可以使用转义字符:

1
2
3
4
换行:\n
回车:\r
水平制表符:\t
退格:\b
1
2
3
4
print("hello\nworld")   
print("hello\tworld")
print("hello\rworld") #world将hello进行了覆盖
print("hello\bworld") #\b是退一个格,将o退没了
1
2
3
4
5
hello
world
hello world
world
hellworld

原字符:不希望字符串中的转义字符起作用,在字符串前面加上r或R

1
print(r"hello\nworld")   
1
hello\nworld

注意事项:最后一个字符不能是反斜线

二、变量

变量的定义与赋值

1.定义一个变量

1
2
word = '变量'
print(word)
1
变量

2.变量的多次赋值

1
2
3
name = '张三'
name = '李四'
print(name)
1
李四

常用的数据类型

1
2
3
4
整数类型		->int		->97
浮点类型 ->float ->3.1415
布尔类型 ->bool ->True,False
字符串类型 ->str ->'人生苦短'

1.整数类型

整数可以表示正数、负数和零,也可以表示为二进制、十进制、八进制、十六进制

1
2
3
4
5
6
7
8
9
10
11
n1 = 90
n2 = -76
n3 = 0
print(n1,type(n1))
print(n2,type(n2))
print(n3,type(n3))
#整数可以表示为二进制、十进制、八进制、十六进制
print('十进制',118)
print('二进制',0b1010111)
print('八进制',0o176)
print('十六进制',0x1EAF)
1
2
3
4
5
6
7
90 <class 'int'>
-76 <class 'int'>
0 <class 'int'>
十进制 118
二进制 87
八进制 126
十六进制 7855

整数的不同进制表示方式:

1
2
3
4
十进制		->默认的进制
二进制 ->以0b开头
八进制 ->以0o开头
十六进制 ->以0x开头

2.浮点类型

浮点数由整数部分和小数部分组成

浮点数存储不精确性

使用浮点数进行计算时,可能会出现小数位数不确定的情况

1
2
3
a = 3.1415
print(a,type(a))
print(1.1 + 2.2)
1
2
3.1415 <class 'float'>
3.3000000000000003

导入模块decimal

1
2
from decimal import Decimal
print(Decimal('1.1') + Decimal('2.2'))
1
3.3

3.布尔类型

用来表示真或假的值,True表示真,False表示假

1
2
3
4
f1 = True
f2 = False
print(f1,type(f1))
print(f2,type(f2))
1
2
True <class 'bool'>
False <class 'bool'>

布尔值可以转化为整数,True表示1,False表示0

1
2
print(True + 1)
print(False + 1)
1
2
2
1

4.字符串类型

字符串又称为不可变的字符序列,可以用单引号、双引号、三引号来定义,单引号和双引号定义的字符串必须在一行,三引号定义的字符串可以分布在连续的多行

1
2
3
4
5
6
7
8
9
10
word = '字符串'
sentence = "这是一个句子"
paragraph = """
这是一个段落
可以由多行组成
"""

print(word)
print(sentence)
print(paragraph)
1
2
3
4
5
6
7
字符串 <class 'str'>
这是一个句子 <class 'str'>

这是一个段落
可以由多行组成
<class 'str'>

数据类型转换

将不同数据类型的数据拼接在一起时会报错

1
2
3
4
name = '张三'
age = 20
print(type(name),type(age))
print('我叫' + name + ',今年' + age + '岁')
1
2
3
4
5
Traceback (most recent call last):
File "C:\Software\PycharmProjects\demo1\demo2.py", line 128, in <module>
print('我叫' + name + ',今年' + age + '岁')
TypeError: can only concatenate str (not "int") to str
<class 'str'> <class 'int'>

使用函数将int转换成str类型不会报错

1
2
3
4
name = '张三'
age = 20
print(type(name),type(age))
print('我叫' + name + ',今年' + str(age) + '岁')
1
2
<class 'str'> <class 'int'>
我叫张三,今年20岁
函数名 作用 注意事项 举例
str() 将其他数据类型转换成字符串 也可用引号转换 str(123)
'123'
int() 将其他数据类型转换成整数 文字类和小数类字符串,无法转化成整数 int('123')
浮点数转化成整数:抹零取整 int(9.8)
float() 将其他数据类型转换成浮点数 文字类无法转成整数 float(‘9.9’)
整数转成浮点数,末尾为.0 float(9)

进阶学习

结合%s%d打印变量,%s代表字符串,%d代表数字

1
2
3
4
5
a = 123
b = "abc"
print("这是%d"%a)
print("这是%s"%b)
print("%d和%s"%(a,b))
1
2
3
这是123
这是abc
123和abc

结合下标打印字符串

1
2
3
4
5
6
str = "beijing"
print(str)
print(str[0:3]) #[起始位置:结束为止:步进值]
print(str[0:])
print(str[:5])
print(str[0:len(str):2]) #len()表示字符串的长度
1
2
3
4
5
beijing
bei
beijing
beiji
biig

拼接字符串

1
2
3
4
5
6
str = "beijing"
print(str[0:]) #beijing
print(str[:5]) #beiji

print(str + ",你好") #beijing,你好
print(str * 3) #beijingbeijingbeijing
1
2
3
4
beijing
beiji
beijing,你好
beijingbeijingbeijing

三、运算符

input()函数的使用

接收来自用户的输入,输入的值类型为str,也可以使用=对输入的值进行存储

1
2
present = input('想要什么礼物呢?')
print(present)
1
2
想要什么礼物呢?钱

常用运算符

1.算术运算符

算术运算符
标准算术运算符 加(+)、减(-)、乘(*)、除(/)、整除(//)
取余运算符 %
幂运算符 **
运算符 表示 例子 结果
+ 1+1 2
- 1-1 0
* 2*4 8
/ 1/2 0.5
% 取余(一正一负要公式) 9%4 1
余数=被除数-除数*商 9%-4
9-(-4)*(-3)
-3
** 幂运算 2**3 8
// 整数(一正一负向下取整) 11//2 5
9//-4 -3
-9//4 -3

2.赋值运算符

赋值运算符的执行顺序为从右向左,支持链式赋值(a=b=c=20)、参数赋值(+=,-=,*=,/=,//=,%=),以及系列解包赋值(a,b,c=20,30,40)

3.比较运算符

比较运算符有大于(>)、小于(<)、大于或等于(>=)、小于或等于(<=)、不等于(!=)以及对象value的比较(==),还有is和is not这种比较对象id的比较运算符

4.布尔运算符

运算符 运算数 运算结果 备注
and True True True 当两个运算数都为True时,运算结果才为True
True False False
False True
False False
or True True True 只要有一个运算数为True,运算结果就为True
True False
False True
False False False
not True False 如果运算数为True,运算结果为False
False True 如果运算数为False,运算结果为True
in 'e' in 'hello' True 如果字符串中包含指定字符,运算结果为True
'i' in 'hello' False 如果字符串中不包含指定字符,运算结果为False
not in 'e' not in 'hello' False 如果字符串中包含指定字符,运算结果为False
'i' in 'hello' True 如果字符串中不包含指定字符,运算结果为True

5.位运算符

运算符 备注
位与& 对应数位都是1,结果数位才是1,否则为0
位或 | 对应数位都是0,结果数位才是0,否则为1
左移位运算符 << 高位溢出舍弃,低位补0
右移位运算符 >> 低位溢出舍弃,高位补0

运算符的优先级

括号()>算术运算符>位运算符>比较运算符>布尔运算符>赋值运算符

四、if判断以及for、while循环

if条件判断

判断符合条件既执行语句:

1
2
3
4
if True:
print("符合")
else:
print("不符合")
1
符合

1.案例

结合input()函数实现查询成绩系统:

1
2
3
4
5
6
7
8
9
10
11
score = int(input("请输入你的成绩:"))
if score >= 90 and score <= 100:
print("本次考试,等级为A")
elif score >= 80 and score <= 90:
print("本次考试,等级为B")
elif score >= 70 and score <= 80:
print("本次考试,等级为C")
elif score >= 60 and score <= 70:
print("本次考试,等级为D")
else:
print("本次考试,等级为E")
1
2
请输入你的成绩:89
本次考试,等级为B

2.pass语句

语句什么都不做,只是一个占位符,用在语法上需要语句的地方(一般在还没想好代码怎么写,先搭建语法结构的时候使用),可以和if语句的条件执行体、for-in语句的循环体以及定义函数时的函数体一起使用

3.range函数的使用

range()函数用于生成一个整数序列,返回值是一个迭代器对象。
创建range对象的三种方式:

range(stop) 创建一个[0,stop)之间的整数序列,步长为1
range(start,stop) 创建一个[start,stop)之间的整数序列,步长为1
range(start,stop,step) 创建一个[start,stop)之间的整数序列,步长为step

优点:不管range对象表示的整数序列有多长,所有range对象占用的内存空间都是相同的,因为仅仅需要存储start,stop和step,只有当用到range对象时,才会去计算序列中的相关元素

for循环

循环5次:

1
2
for i in range(5):
print(i)
1
2
3
4
5
0
1
2
3
4

以3递增打印从0到10:

1
2
for i in range(0,10,3):
print(i)
1
2
3
4
0
3
6
9

负数同样也可以递增:

1
2
for i in range(-10,-100,-30):
print(i)
1
2
3
-10
-40
-70

也可以循环打印字符串:

1
2
for x in "beijing":
print(x,end="\t") #end表示以什么为结尾,默认为\n
1
b	e	i	j	i	n	g	

while循环

循环5次:

1
2
3
4
5
i = 0
while i < 5 :
print("当前是第%d次执行循环"%(i+1))
print("i=%d"%i)
i += 1
1
2
3
4
5
6
7
8
9
10
当前是第1次执行循环
i=0
当前是第2次执行循环
i=1
当前是第3次执行循环
i=2
当前是第4次执行循环
i=3
当前是第5次执行循环
i=4

1.案例

1-100求和:

1
2
3
4
5
6
i = 0
sum = 0
while i <= 100:
sum += i
i += 1
print("1-100求和结果:%d"%sum)
1
1-100求和结果:5050

2.while和else结合使用

while也可以和else结合使用:

1
2
3
4
5
6
count = 0
while count < 5 :
print(count,"小于5")
count += 1
else:
print(count,"大于或等于5")
1
2
3
4
5
6
0 小于5
1 小于5
2 小于5
3 小于5
4 小于5
5 大于或等于5

break和continue

1.break

使用break结束此次循环:

1
2
3
4
5
6
7
i = 0
while i < 10 :
i = i+1
if i == 5 :
break
print("-"*30)
print(i)
1
2
3
4
5
6
7
8
------------------------------
1
------------------------------
2
------------------------------
3
------------------------------
4

2.continue

使用continue跳过当前循环

1
2
3
4
5
6
7
i = 0
while i < 10 :
i = i+1
if i == 5 :
continue
print("-" * 30)
print(i)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
------------------------------
1
------------------------------
2
------------------------------
3
------------------------------
4
------------------------------
6
------------------------------
7
------------------------------
8
------------------------------
9
------------------------------
10

九九乘法表的实现

经典案例:九九乘法表

1
2
3
4
5
6
7
8
9
10
i = 1
j = 1
while i <= 9 :
x = 1
while x <= j :
print("%d*%d=%d"%(i,x,i*x),end="\t")
x += 1
i += 1
j += 1
print()
1
2
3
4
5
6
7
8
9
1*1=1	
2*1=2 2*2=4
3*1=3 3*2=6 3*3=9
4*1=4 4*2=8 4*3=12 4*4=16
5*1=5 5*2=10 5*3=15 5*4=20 5*5=25
6*1=6 6*2=12 6*3=18 6*4=24 6*5=30 6*6=36
7*1=7 7*2=14 7*3=21 7*4=28 7*5=35 7*6=42 7*7=49
8*1=8 8*2=16 8*3=24 8*4=32 8*5=40 8*6=48 8*7=56 8*8=64
9*1=9 9*2=18 9*3=27 9*4=36 9*5=45 9*6=54 9*7=63 9*8=72 9*9=81

五、列表

列表的定义

列表相当于其他语言中的数组

1
namelist = []   #定义一个空的列表
1
2
3
4
namelist = ["李","王","张"]
print(namelist[0])
print(namelist[1])
print(namelist[2])
1
2
3



列表的创建

使用中括号

1
lst=['张三','李四']

使用内置函数list()

1
lst=list(['张三','李四'])

列表的特点

  • 列表元素按顺序有序排序
  • 索引映射唯一一个数据
  • 列表可以存储重复数据
  • 任意数据类型混存
  • 根据需要动态分配和回收内存

存储混合类型:

1
namelist = []   #定义一个空的列表
1
2
3
testlist = [1,"测试"]
print(type(testlist[0])) #type()能辨别字符串的类型
print(type(testlist[1]))
1
2
<class 'int'>
<class 'str'>

结合循环打印列表元素:

1
2
3
4
5
6
7
8
namelist = ["李","王","张"]
for name in namelist :
print(name)
print("-" * 30)
i = 0
while i<len(namelist) :
print(namelist[i])
i += 1
1
2
3
4
5
6
7



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



多维列表:

1
2
3
4
5
#a = [[],[],[]]      #三个元素的空列表,每个元素都是一个空列表
a = [[1,2],[3,4]]
print(a)
print(a[0])
print(a[0][0])
1
2
3
[[1, 2], [3, 4]]
[1, 2]
1

增删改查

1.增

列表增加元素使用extend或append方法
extend:

1
2
3
4
5
6
7
8
9
namelist = ["李","王","张"]
print("-----增加前数据-----")
for name in namelist :
print(name)

namelist.append(input("请输入添加的姓:"))
print("-----增加后数据-----")
for name in namelist :
print(name)
1
2
3
4
5
6
7
8
9
10
-----增加前数据-----



请输入添加的姓:魏
-----增加后数据-----




append:

1
2
3
4
a = [1,2]
b = [3,4]
a.append(b) #将列表当作一个元素,加入到另一列表中
print(a)
1
[1, 2, [3, 4]]

2.删

删除列表的元素
del、pop、remove均可:

1
2
3
4
5
6
7
8
9
10
a = [1,2,3]
print("-----删除前数据-----")
for num in a :
print(num)
#del a[1] #删除指定下标的数据
#a.pop() #弹出末尾最后一个元素
a.remove(2) #直接删除指定内容的元素
print("-----删除后数据-----")
for num in a :
print(num)
1
2
3
4
5
6
7
-----删除前数据-----
1
2
3
-----删除后数据-----
1
3

3.改

修改列表元素:

1
2
3
4
5
6
7
8
a = [1,2,3]
print("-----修改前数据-----")
for num in a :
print(num)
a[1] = 5 #修改指定下标的元素内容
print("-----修改后数据-----")
for num in a :
print(num)
1
2
3
4
5
6
7
8
-----修改前数据-----
1
2
3
-----修改后数据-----
1
5
3

4.查

查询指定元素:
in或not in:

1
2
3
4
5
a = [1,2,3]
if int(input("请输入你要查找的数字:")) in a :
print("YES")
else:
print("NO")
1
2
请输入你要查找的数字:3
YES

查找指定下标范围的元素,并返回对应元素的下标:

1
2
3
a = [1,2,3,4,5,6]
print(a.index(3,1,4))
#print(a.index(4,1,3)) #找不到会报错 范围区间:左闭右开 [1,3)
1
2

列表常用方法

统计:

1
2
a = [1,4,3,2,5,6]
print(a.count(2)) #统计某个元素出现过几次
1
1

将所有元素反转:

1
2
3
a = [1,4,3,2,5,6]
a.reverse()
print(a)
1
[6, 5, 2, 3, 4, 1]

升序:

1
2
3
a = [1,4,3,2,5,6]
a.sort()
print(a)
1
[1, 2, 3, 4, 5, 6]

降序:

1
2
3
a = [1,4,3,2,5,6]
a.sort(reverse=True)
print(a)
1
[6, 5, 4, 3, 2, 1]

列表生成式

[i*i for i in range(1,10)]
注意事项:i表示列表元素的表达式(通常包含自定义变量),for-in中的i表示自定义变量,range(1,10)表示可迭代对象

1
2
3
4
lst=[i*i for i in range(1,10)]
print(lst)
lst2=[i*2 for i in range(1,6)]
print(lst2)
1
2
[1, 4, 9, 16, 25, 36, 49, 64, 81]
[2, 4, 6, 8, 10]

案例

8个老师随机分到三个学校里:
随机数用random.randint()方法生成,需要import random:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
import random
offices = [[],[],[]]

names = ["A","B","C","D","E","F","G","H"]

for name in names :
index = random.randint(0,2)
offices[index].append(name)

i = 1
for office in offices :
print("办公室%d的人数为:%d"%(i,len(office)))
i += 1
for name in office :
print("%s"%name,end="\t")
print()
1
2
3
4
5
6
办公室1的人数为:5
A B D F H
办公室2的人数为:2
E G
办公室3的人数为:1
C

购物车:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
products = [["iphone",6888],["MacPro",14800],["小米6",2499],["Coffee",31],["Book",60],["Nike",699]]
print("------\t商品列表\t------")
for product in products :
print(products.index(product),end="\t")
print(product[0],end="\t")
print(product[1])
num = 0
cars = []
while num != "q" :
num = input("请输入您要购买商品的编号:")
if num == "q" :
break
cars.append(products[int(num)])
print("您购物车的商品有:")
for car in cars :
print(car)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
------	商品列表	------
0 iphone 6888
1 MacPro 14800
2 小米6 2499
3 Coffee 31
4 Book 60
5 Nike 699
请输入您要购买商品的编号:1
请输入您要购买商品的编号:4
请输入您要购买商品的编号:3
请输入您要购买商品的编号:0
请输入您要购买商品的编号:q
您购物车的商品有:
['MacPro', 14800]
['Book', 60]
['Coffee', 31]
['iphone', 6888]

使用enumerate()枚举函数可以同时拿到列表中的下标和元素:

1
2
3
4
5
6
mylist = ["a","b","c","d","e"]

print(enumerate(mylist)) #<enumerate object at 0x000001F711412C00>

for i,x in enumerate(mylist):
print(i,x)
1
2
3
4
5
6
<enumerate object at 0x000001C3B09A8E00>
0 a
1 b
2 c
3 d
4 e

可以使用枚举函数优化上面的购物车案例

六、字典

字典的定义

字典的实现原理与查字典类似,查字典是先根据部首或拼音查找对应的页码,Python中的字典是根据key查找value所在的位置

1
info = {"name":"吴彦祖","age":18}
1
TypeError: 'tuple' object does not support item assignment

字典的创建

使用花括号:

1
scores={'张三':100,'李四':98,'王五':45}

使用内置函数dict():

1
dict(name='张三',age=20)

字典的特点

  • 字典中的所有元素都是一个key-value对,key不允许重复,value可以重复
  • 字典中的元素是无序的
  • 字典中的key必须是不可变对象
  • 字典也可以根据需要动态地伸缩
  • 字典会浪费较大的内存,是一种使用空间换时间的数据结构

增删改查

1.增

1
2
3
info = {"name":"吴彦祖","age":18}
info["id"] = 1
print(info["id"]) #1
1
1

2.删

del:

1
2
3
4
5
6
info = {"name":"吴彦祖","age":18}
print("删除前:%s"%info["name"])
del info["name"]
print("删除后:%s"%info["name"]) #删除了指定键值对后,再次访问会报错
del info
print("删除后:%s"%info) #删除字典后再访问,报错
1
2
KeyError: 'name'
NameError: name 'info' is not defined

clear:

1
2
3
4
5
6
info = {"name":"吴彦祖","age":18}
print("清空前:%s"%info) #清空前:{'name': '吴彦祖', 'age': 18}

info.clear()

print("清空后:%s"%info) #清空后:{}
1
2
清空前:{'name': '吴彦祖', 'age': 18}
清空后:{}

3.改

1
2
3
info = {"name":"吴彦祖","age":18}
info["age"] = 20
print(info["age"]) #20
1
20

4.查

通过get()方法或直接[中括号]获取value

1
2
3
4
5
6
info = {"id":"1","name":"吴彦祖","age":18}
print(info['id']) #获取key为id的value
print(info.get("name")) #获取key为name的value
print(info.keys()) #得到所有键(列表)
print(info.values()) #得到所有的值(列表)
print(info.items()) #得到所有的项(列表),每个键值对是一个元组
1
2
3
4
5
1
吴彦祖
dict_keys(['id', 'name', 'age'])
dict_values(['1', '吴彦祖', 18])
dict_items([('id', '1'), ('name', '吴彦祖'), ('age', 18)])

遍历所有的键

1
2
3
info = {"name":"吴彦祖","age":18}
for key in info.keys():
print(key)
1
2
3
id
name
age

遍历所有的值

1
2
3
info = {"name":"吴彦祖","age":18}
for value in info.values():
print(value)
1
2
3
1
吴彦祖
18

遍历所有的键值对

1
2
3
info = {"name":"吴彦祖","age":18}
for key,value in info.items():
print("key=%s,value=%s"%(key,value))
1
2
3
key=id,value=1
key=name,value=吴彦祖
key=age,value=18

访问字典不存在的key时:

1
2
3
4
5
info = {"name":"吴彦祖","age":18}
#print(info["gender"]) #直接访问 报错
print(info.get("age"))
print(info.get("gender")) #使用get方法没有找到对应的键,默认返回None
print(info.get("gender","m")) #m 没找到的时候,可以设定默认值
1
2
3
18
None
m

字典生成式

内置函数zip(),用于将可迭代的对象作为参数,将对象中对应的元素打包成一个元组,然后返回由这些元组组成的列表

1
2
3
4
a=['Fruits','Books','Others']
b=[96,78,85]
lst=zip(a,b)
print(list(lst))
1
[('Fruits', 96), ('Books', 78), ('Others', 85)]

七、元组

元组的定义

Python内置的数据结构之一,是一个不可变序列

  • 不可变序列:字符串、元组
    • 不可变序列:没有增、删、改的操作
  • 可变序列:列表、字典
    • 可变序列:可以对序列执行增、删、改操作,对象地址不发生改变

元组的创建

直接使用小括号:

1
2
t1=()   #创建空的元组
t2=('Python','hello',10)

使用内置函数tuple()

1
tup1=tuple('Python','hello',10)

只包含一个元素的元组需要使用逗号和小括号:

1
t1=(10,)

元组为不可变序列的原因

在多任务环境下,同时操作对象时不需要加锁
注意事项:
如果元组中对象本身是不可变对象,则不能再引用其他对象
如果元组中的对象是可变对象,则可变对象的引用不允许改变,但数据可以改变

增删改查

1.增(连接)

1
2
3
4
5
tup1 = (12,34,56)
tup2 = ("abc","def")

tup = tup1 + tup2
print(tup)
1
(12, 34, 56, 'abc', 'def')

2.删

del,删除会删掉整个元组:

1
2
3
4
5
tup1 = (12,34,56)
print(tup1) #(12, 34, 56)
del tup1 #删除了整个元组
print("删除后:")
print(tup1) #报错
1
NameError: name 'tup1' is not defined

3.改(元组不允许修改)

1
2
tup1 = (12,34,56)
tup1[0] = 10 #报错,不允许修改
1
TypeError: 'tuple' object does not support item assignment

4.查

1
2
3
4
5
tup1 = ("abc","def",2000,2001)
print(tup1[0])
print(tup1[-1])
print(tup1[1])
print(tup1[0:2]) #('abc', 'def') 左闭右开
1
2
3
4
abc
2001
def
('abc', 'def')

注:元组没有生成式

八、集合

集合的定义

与列表、字典一样都属于可变类型的序列,集合是没有value的字典

集合的创建

直接使用大括号

1
s={'python','hello',10}

使用内置函数set()

1
2
3
4
5
6
7
s=set(range(6))
print(s)
print(set([1,2,3,4,5]))
print(set((1,2,3,4,5)))
print(set('python'))
print(set({1,2,3,4,5}))
print(set())
1
2
3
4
5
6
{0, 1, 2, 3, 4, 5}
{1, 2, 3, 4, 5}
{1, 2, 3, 4, 5}
{'o', 'y', 'p', 'h', 'n', 't'}
{1, 2, 3, 4, 5}
set()

集合的相关操作

1.判断操作

in

1
2
3
s={10,20,30,40,50}
print(10 in s)
print(60 in s)
1
2
True
False

not in

1
2
3
s={10,20,30,40,50}
print(10 not in s)
print(60 not in s)
1
2
False
True

2.新增操作

通过add()方法,一次添加一个元素

1
2
3
s={10,20,30,40,50}
s.add{60}
print(s)
1
{50, 20, 40, 10, 60, 30}

通过update()方法,至少添加一个元素

1
2
3
s={10,20,30,40,50}
s.update({100,200,300})
print(s)
1
{50, 20, 100, 40, 10, 300, 30, 200}

3.删除操作

通过remove()方法,一次删除一个指定元素,如果指定的元素不存在就抛出KeyError

1
2
3
s={10,20,30,40,50}
s.remove(100)
print(s)
1
2
3
4
Traceback (most recent call last):
File "C:\Software\PycharmProjects\demo1\demo2.py", line 133, in <module>
s.remove(100)
KeyError: 100

通过discard()方法,一次删除一个指定元素,如果指定的元素不存在不抛异常

1
2
3
s={10,20,30,40,50}
s.discard(100)
print(s)
1
{50, 20, 40, 10, 30}

通过pop()方法,一次只删除一个任意元素

1
2
3
s={10,20,30,40,50}
s.pop()
print(s)
1
{20, 40, 10, 30}

通过clear()方法,清空集合

1
2
3
s={10,20,30,40,50}
s.clear()
print(s)
1
set()

集合间的关系

可以用运算符==或!=来判断两个集合是否相等

1
2
3
4
s1={10,20,30,40,50}
s2={30,50,10,20,40}
print(s1==s2)
print(s1!=s2)
1
2
True
False

通过issubset方法判断一个集合是否是另一个集合的子集

1
2
3
4
5
s1={10,20,30,40,50}
s2={10,30,50}
s3={10,60}
print(s2.issubset(s1))
print(s3.issubset(s1))
1
2
True
False

通过issuperset方法判断一个集合是否是另一个集合的超集

1
2
3
4
5
s1={10,20,30,40,50}
s2={10,30,50}
s3={10,60}
print(s1.issuperset(s2))
print(s1.issuperset(s3))
1
2
True
False

通过isdisjoint判断两个集合是否有交集

1
2
3
4
5
s1={10,20,30}
s2={30,40,50}
s3={40,50,60}
print(s1.isdisjoint(s2)) #有交集返回False
print(s1.isdisjoint(s3)) #无交集返回True
1
2
False
True

集合的数学操作

1.交集

1
2
3
4
s1={10,20,30}
s2={20,30,40,50,60}
print(s1.intersection(s2))
print(s1 & s2) #intersection()与 & 等价,交集操作
1
2
{20, 30}
{20, 30}

2.并集

1
2
3
4
s1={10,20,30}
s2={20,30,40,50,60}
print(s1.union(s2))
print(s1 | s2) #union与 | 等价,并集操作
1
2
{40, 10, 50, 20, 60, 30}
{40, 10, 50, 20, 60, 30}

3.差集

1
2
3
4
s1={10,20,30}
s2={20,30,40,50,60}
print(s1.difference(s2))
print(s1 - s2) #difference与 - 等价,差集操作
1
2
{10}
{10}

4.对称差集

1
2
3
4
s1={10,20,30}
s2={20,30,40,50,60}
print(s1.symmetric_difference(s2))
print(s1^s2) #symmetric_difference与 ^ 等价,对称差集操作
1
2
{50, 40, 10, 60}
{50, 40, 10, 60}

集合生成式

{i*i for i in range(num)}

1
2
s={i*i for i in range(6)}
print(s)
1
{0, 1, 4, 9, 16, 25}

九、列表、字典、元组、集合总结

数据结构 是否可变 是否重复 是否有序 定义符号
列表(list) 可变 可重复 有序 []
元组(tuple) 不可变 可重复 有序 ()
字典(dict) 可变 key不可重复 无序 {key:value}
value可重复
集合(set) 可变 不可重复 无序 {}

十、字符串(进阶)

Python中字符串是基本数据类型,是一个不可变的字符序列

字符串驻留机制

仅保留一份相同且不可变字符串的方法,不同的值被存放在字符串的驻留池中,Python的驻留机制对相同的字符串只保留一份拷贝,后续创建相同字符串时,不会开辟新空间,而是把该字符串的地址赋给新创建的变量

1
2
3
4
5
6
a='python'
b='python'
c='python'
print(a,id(a))
print(b,id(b))
print(c,id(c))
1
2
3
python 2785734751984
python 2785734751984
python 2785734751984

驻留模式的几种情况(交互模式)

  • 字符串的长度为0或1时
1
2
3
4
5
6
a=0
b=0
print(a is b)
a1='%'
b1='%'
print(a1 is b1)
1
2
True
True
  • 符合标识符的字符串
1
2
3
4
5
6
7
a='abc%'
b='abc%'
print(a==b)
print(a is b)
a1='abc'
b1='abc'
print(a1 is b1)
1
2
3
True
False
True
  • 字符串只在编译时进行驻留,而非运行时
1
2
3
4
5
6
a='abc'
b='ab' + 'c'
c=''.join(['ab','c'])
print(c)
print(a is b)
print(a is c)
1
2
3
abc
True
False
  • [-5,256]之间的整数数字
1
2
3
4
5
6
a=-5
b=-5
print(a is b)
a1 = -6
b1 = -6
print(a1 is b1)
1
2
True
False

可以通过sys.intern方法强制驻留

1
2
3
4
a = -6
b = -6
a = sys.intern(b)
print(a is b)
1
True

注:PyCharm对字符串进行了优化处理,所以上面的效果在PyCharm中无法演示

驻留机制的优缺点

  • 当需要值相同的字符串时,可以直接从字符串池里拿来使用,避免频繁的创建和销毁,提升效率和节约内存,因此拼接字符串和修改字符串是会比较影响性能的
  • 在需要进行字符串拼接时建议使用str类型的join方法,而非“+”,因为json()方法是先计算出所有字符中的长度,然后再拷贝,只new一次对象,效率要比“+”效率高

字符串的常用操作

1.查询操作

功能 方法名称 作用
查询方法 index() 查找子串substr第一次出现的位置,如果查找的子串不存在时,则抛出ValueError
rindex() 查找子串substr最后一次出现的位置,如果查找的子串不存在时,则抛出ValueError
find() 查找子串substr第一次出现的位置,如果查找的子串不存在时,则返回-1
rfind() 查找子串substr最后一次出现的位置,如果查找的子串不存在时,则返回-1

2.大小写转换

功能 方法名称 作用
大小写转换 upper() 把字符串中所有字符都转成大写字符
lower() 把字符串中所有字符都转成小写字符
swapcase() 把字符串中所有大写字母转成小写字母,把所有小写字母都转成大写字母
capitalize() 把第一个字符转换为大写,其余字符转换为小写
title() 把每个单词的第一个字符转换为大写,把每个单词的剩余字符转换为小写

3.内容对齐操作

功能 方法名称 作用
字符串对齐 center() 居中对齐,第1个参数指定宽度,第2个参数指定填充符,第2个参数是可选的,默认是空格,如果设置宽度小于实际宽度则返回原字符串
ljust() 左对齐,第1个参数指定宽度,第2个参数指定填充符,第2个参数是可选的,默认是空格,如果设置宽度小于实际宽度则返回原字符串
rjust() 右对齐,第1个参数指定宽度,第2个参数指定填充符,第2个参数是可选的,默认是空格,如果设置宽度小于实际宽度则返回原字符串
zfill() 右对齐,左边用0填充,该方法只接收一个参数,用于指定字符串的宽度,如果指定的宽度小于等于字符串的长度,返回字符串本身

4.劈分操作

功能 方法名称 作用
字符串的劈分 split() 从字符串的左边开始劈分,默认的劈分字符是空格字符串,返回的值都是一个列表
以通过参数sep指定劈分字符串的劈分符
通过参数maxsplit指定劈分字符串时的最大劈分次数,在经过最大次劈分之后,剩余的子串会单独做为一部分
rsplit() 从字符串的右边开始劈分,默认的劈分字符是空格字符串,返回的值都是一个列表
以通过参数sep指定劈分字符串的劈分符
通过参数maxsplit指定劈分字符串时的最大劈分次数,在经过最大次劈分之后,剩余的子串会单独做为一部分

5.判断字符串操作

功能 方法名称 作用
判断字符串的方法 isidentifier() 判断指定的字符串是不是合法的标识符
isspace() 判断指定的字符串是否全部由空白字符组成(回车、换行、水平制表符)
isalpha() 判断指定的字符串是否全部由字母组成
isdecimal() 判断指定字符串是否全部由十进制的数字组成
isnumeric() 判断指定的字符串是否全部由数字组成
isalnum() 判断指定字符串是否全部由字母和数字组成

6.替换与合并操作

功能 方法名称 作用
字符串替换 replace() 第1个参数指定被替换的子串,第2个参数指定替换子串的字符串,该方法返回替换后得到的字符串,替换前的字符串不发生变化,调用该方法时可以通过第3个参数指定最大替换次数
字符串的合并 join() 将列表或元组中的字符串合并成一个字符串

7.比较操作

  • 运算符:>、>=、<、<=、==、!=
  • 比较规则: 首先比较两个字符串中的第一个字符串,如果相等则继续比较下一个字符,依次比较下去,直到两个字符串中的字符不相等时,其比较结果就是两个字符串的比较结果,两个字符串中的所有后续字符将不再被比较
  • 比较原理: 两个字符进行比较时,比较的是其ordinal value(原始值),调用内置函数ord可以得到指定字符的ordinal value。与内置函数ord对应的是内置函数chr,调用内置函数chr时指定的ordinal value可以得到其对应的字符

8.切片操作

  • 字符串是不可变类型
  • 不具备增、删、改等操作
  • 切片操作将产生新的对象
1
2
3
4
5
str = 'python,hello'
print(str[1:5:1]) #从1开始截到5(不包含5),步长为1
print(str[::2]) #默认从0开始,没有写结束,默认到字符串的最后一个元素,步长为2
print(str[::-1]) #默认从字符串的最后一个元素开始,到字符串的第一个元素结束,因为步长为负数
print(str[-6::1]) #从索引为-6开始,到字符串的最后一个元素,步长为1
1
2
3
4
ytho
pto,el
olleh,nohtyp
,hello

9.格式化字符串

  • %作占位符
1
2
3
4
name = '张三'
age = 66
print("我的名字叫:%s,今年66岁了"%name)
print("我的名字叫:%s,今年%d岁了"%(name,age))
1
2
我的名字叫:张三,今年66岁了
我的名字叫:张三,今年66岁了
  • {}作占位符
1
2
3
name = '张三'
age = 66
print("我的名字叫:{0},今年{1}岁了,{0}".format(name,age))
1
我的名字叫:张三,今年66岁了,张三

10.字符串的编码与解码

  • 编码: 将字符串转换为二进制数据(bytes)
1
2
3
str='海内存知己'
print(str.encode(encoding='GBK')) #在GBK这种编码格式中,一个中文占两个字节
print(str.encode(encoding='UTF-8')) #在UTF-8这种编码格式中,一个中文占三个字节
1
2
b'\xba\xa3\xc4\xda\xb4\xe6\xd6\xaa\xbc\xba'
b'\xe6\xb5\xb7\xe5\x86\x85\xe5\xad\x98\xe7\x9f\xa5\xe5\xb7\xb1'
  • 解码: 将bytes类型的数据转换成字符串类型
1
2
3
4
5
6
str='海内存知己'
byte = str.encode(encoding='GBK')
print(byte.decode(encoding='GBK'))

byte = str.encode(encoding='UTF-8')
print(byte.decode(encoding='UTF-8'))
1
2
海内存知己
海内存知己

十一、函数

函数的创建和调用

函数就是执行特定任务以完成特定功能一段代码

  • 为什么要使用函数
    • 复用代码
    • 隐藏实现细节
    • 提高可维护性
    • 提高可读性便于调试

函数的创建及调用:

1
2
3
4
5
6
#函数的创建
def printinfo():
print("-------人生苦短-------")

#函数的调用
printinfo()
1
-------人生苦短-------

函数的参数传递

  • 位置实参
    • 根据形参对应的位置进行实参传递
1
2
3
4
5
def calc(a,b):	#a,b称为形式参数,简称形参,形参的位置是在函数的定义处
c=a+b
return c
result=calc(1,2) #1,2称为实际参数,简称实参,实参的位置在函数的调用处
print(result)
1
3
  • 关键字实参
    • 根据形参名称进行实参传递
1
2
3
4
5
6
7
8
def calc(a,b):	#a,b称为形式参数,简称形参,形参的位置是在函数的定义处
def calc(a,b):
print(a)
print(b)
c=a+b
return c
result=calc(b=1,a=2)
print(result)
1
2
3
2
1
3
  • 个数可变的位置形参
    • 定义函数时,可能无法事先确定传递的位置实参的个数时,使用可变的位置参数
    • 使用*定义个数可变的位置形参
    • 结果为一个元组
1
2
3
4
def fun(*args):
print(args)
fun(10)
fun(10,20,30)
1
2
(10,)
(10, 20, 30)
  • 个数可变的关键字形参
    • 定义函数时,无法事先确定传递的关键字实参的个数时,使用可变的关键字形参
    • 使用**定义个数可变的关键字形参
    • 结果为一个字典
1
2
3
4
def fun(**args):
print(args)
fun(a=10)
fun(a=10,b=20,c=30)
1
2
{'a': 10}
{'a': 10, 'b': 20, 'c': 30}

函数的返回值

  • 如果函数没有返回值,return可以省略不写
1
2
3
def fun():
print('hello')
fun()
1
hello
  • 函数的返回值如果是一个,只返回一个类型
1
2
3
def fun():
return 'hello'
print(fun())
1
hello
  • 函数的返回值如果是多个,返回的结果为元组
1
2
3
4
5
6
7
8
9
10
11
def fun(num):
odd=[] #存奇数
even=[] #存偶数
for i in num:
if i%2:
odd.append(i)
else:
even.append(i)
return odd,even
lst=[1,2,3,4,5,6,7,8,9,0]
print(fun(lst))
1
([1, 3, 5, 7, 9], [2, 4, 6, 8, 0])

函数定义默认值传参

1
2
3
4
def fun(a,b=10):
print(a,b)
fun(100) #只传一个参数,b采用默认值
fun(10,20) #20将替换10
1
2
100 10
10 20

函数的参数总结

序号 参数的类型 函数的定义 函数的调用 备注
1 位置实参
将序列的每个元素都转换为位置实参 使用*
2 关键字实参
将字典中的每个键值对都转换为关键字实参 使用**
3 默认值形参
4 关键字形参 使用*
5 个数可变的位置形参 使用*
6 个数可变的关键字形参 使用**

变量的作用域

  • 程序代码能访问该变量的区域
  • 根据变量的有效范围可分为
    • 局部变量
      • 在函数内定义并使用的变量,只在函数内部有效,局部变量使用global声明,这个变量就会成全局变量
    • 全局变量
      • 函数体外定义的变量,可做用于函数体外

递归函数

  • 递归函数
    • 如果在一个函数的函数体颞部调用了该函数本身,这个函数就称为递归函数
  • 递归的组成
    • 递归调用与递归终止条件
  • 递归的调用过程
    • 每递归调用一次函数,都会在栈内存分配一个栈帧
    • 每执行完一次函数,都会释放相应的空间
  • 递归的优缺点
    • 缺点:占用内存多,效率低下
    • 优点:思路和代码简单

十二、异常处理

捕获异常

  • try…except…结构捕获异常
    • Python提供的异常处理机制,可以在异常出现时及时捕获,然后内部“消化”,让程序继续运行

发生异常:

1
2
3
4
n1=int(input('请输入一个整数:'))
n2=int(input('请输入另一个整数:'))
result=n1/n2
print('结果为:',result)
1
2
3
4
5
6
请输入一个整数:2
请输入另一个整数:jkl
Traceback (most recent call last):
File "C:\Software\PycharmProjects\demo1\demo2.py", line 133, in <module>
n2=int(input('请输入另一个整数:'))
ValueError: invalid literal for int() with base 10: 'jkl'

捕获异常:

1
2
3
4
5
6
7
try:
n1=int(input('请输入一个整数:'))
n2=int(input('请输入另一个整数:'))
result=n1/n2
print('结果为:',result)
except ValueError:
print('输入错误')
1
2
3
请输入一个整数:5
请输入另一个整数:dsf
输入错误
  • 多个except结构
    • 捕获异常的顺序按照先子类后父类的顺序
1
2
3
4
5
6
7
try:
n1=int(input('请输入一个整数:'))
n2=int(input('请输入另一个整数:'))
result=n1/n2
print('结果为:',result)
except (ValueError,Exception): #将可能产生的素有异常类型,都放到下面的小括号里
print('输入错误')
1
2
3
请输入一个整数:6
请输入另一个整数:rew
输入错误

打印异常:

1
2
3
4
5
6
7
8
try:
n1=int(input('请输入一个整数:'))
n2=int(input('请输入另一个整数:'))
result=n1/n2
print('结果为:',result)
except (ValueError,Exception) as result:
print('输入错误')
print(result)
1
2
3
4
请输入一个整数:3
请输入另一个整数:bfg
输入错误
invalid literal for int() with base 10: 'bfg'
  • try…except…else结构
    • 如果try块中没有抛出异常,则执行else块,如果try中抛出异常,则执行except块
1
2
3
4
5
6
7
8
9
try:
n1=int(input('请输入一个整数:'))
n2=int(input('请输入另一个整数:'))
result=n1/n2
except BaseException as e:
print("产生错误了")
print(e)
else:
print('结果为:',result)
  • try…except…else…finally结构
    • finally块无论是否发生异常都会被执行,能常用来释放try块中申请的资源
1
2
3
4
5
6
7
8
9
10
11
try:
n1=int(input('请输入一个整数:'))
n2=int(input('请输入另一个整数:'))
result=n1/n2
except BaseException as e:
print("产生错误了")
print(e)
else:
print('结果为:',result)
finally:
print('程序结束')
  • 使用Exception捕获异常:
1
2
3
4
5
6
7
try:
n1=int(input('请输入一个整数:'))
n2=int(input('请输入另一个整数:'))
result=n1/n2
print('结果为:',result)
except Exception: #Exception可以承接任何异常
print('输入错误')
1
2
3
请输入一个整数:5
请输入另一个整数:dsf
输入错误

Python中常见的异常类型

序号 异常类型 描述
1 ZeroDivisionError 除(或取模)零(所有数据类型)
2 IndexError 序列中没有此索引
3 KeyError 映射中没有这个键
4 NameError 未声明/初始化对象(没有属性)
5 SyntaxError Python语法错误
6 ValueError 传入无效的参数

traceback模块

  • 使用traceback模块打印异常信息
1
2
3
4
5
6
import traceback
try:
print('--------------')
num = 10/0
except:
traceback.print_exc()
1
2
3
4
5
--------------
Traceback (most recent call last):
File "C:\Software\PycharmProjects\demo1\demo2.py", line 135, in <module>
num = 10/0
ZeroDivisionError: division by zero

十三、类、对象、方法

编程的两大思想

面向过程 面向对象
区别 事物比较简单,可以用线性的思维去解决 事物比较复杂,使用简单的线性思维无法解决
共同点 面向过程和面向对象都是解决实际问题的一种思维方式
二者相辅相成,并不是对立
解决复杂问题,通过面向对象方式便于我们从宏观上把握事物之间复杂的关系、方便我们分析整个系统;具体到微观操作,仍然使用面向过程方式来处理

类与对象

    • 类是多个类似事物组成的群体的统称。能够帮助我们快速理解和判断事物的性质
  • 对象
    • 100、99、520都是int类之下包含的相似的不同个例,这个个例专业术语称为实例或对象

1.类的创建

  • 类的组成
    • 类属性:类中方法外的变量称为类属性,被该类的所有对象所共享
    • 实例方法
    • 静态方法:使用@staticmethod修饰的方法,可以通过类名直接访问
    • 类方法:使用@classmethod修饰的方法,可以通过类名直接访问
  • 类的语法
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
class Student:
def __init__(self, name, age): #name,age为实例属性
self.name = name
self.age = age
native_place = "吉林" #类属性
#实例方法
def info(self):
print('我的名字叫:',self.name,'年龄是:',self.age)
#类方法
@classmethod
def cm(cls):
print('类方法')
#静态方法
@staticmethod
def sm():
print('静态方法')

2.对象的创建

  • 对象的创建又称为类的实例化,有了实例就可以调用类中的内容
1
2
3
stu1 = Student('张三',26)
stu1.info()
print(stu1.name)
1
2
我的名字叫: 张三 年龄是: 26
张三

3.类属性、类方法、静态方法的使用

1
2
3
print(Student.native_place)
Student.native_place = '北京'
print(Student.native_place)
1
2
吉林
北京

4.动态绑定属性和方法

  • Python是动态语言,在创建对象之后,可以动态地绑定属性和方法
1
2
3
4
5
6
7
def show():
print('我是一个函数')
stu1 = Student('张三',24)
stu1.gender='男' #动态绑定属性
print(stu1.name,stu1.age,stu1.gender)
stu1.show = show() #动态绑定方法
stu1.show
1
2
张三 24 男
我是一个函数

面向对象的三大特征

1.封装

  • 封装: 提高程序的安全性
    • 将数据(属性)和行为(方法)包装到类对象中。在方法内部对属性进行操作,在类对象的外部调用方法。这样,无需关心方法内部的具体实现细节,从而隔离了复杂度
    • 在Python中没有专门修饰符用于属性的私有,如果该属性不希望在类对象外部被访问,前边使用两个“_”
1
2
3
4
5
6
7
8
9
10
class Student:
def __init__(self, name, age):
self.name = name
self.__age = age
def show(self):
print(self.name,self.__age)
stu1 = Student('张三',24)
stu1.show()
print(stu1.name)
print(stu1.__age)
1
2
3
4
5
6
张三 24
张三
Traceback (most recent call last):
File "C:\Software\PycharmProjects\demo1\demo2.py", line 143, in <module>
print(stu1.__age)
AttributeError: 'Student' object has no attribute '__age'

2.继承

  • 继承: 提高代码的复用性
    • 如果一个类没有继承任何类,则默认继承object
    • Python支持多继承
    • 定义子类时,必须在其构造函数中调用父类的构造函数
1
2
3
4
5
6
7
8
9
10
11
12
13
class Person(object):
def __init__(self, name, age):
self.name = name
self.age = age
def info(self):
print(self.name,self.age)
#定义子类
class Student(Person):
def __init__(self,name,age,score):
super().__init__(name,age)
self.score=score
stu = Student('张三',21,'1000')
stu.info()
1
张三 21

(1)方法重写

  • 方法重写
    • 如果子类对继承自父类的某个属性或方法不满意,可以在子类中对其(方法体)进行重新编写
    • 子类重写后的方法中可以通过super().xxx()调用父类中被重写的方法
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
class Person(object):
def __init__(self, name, age):
self.name = name
self.age = age
def info(self):
print(self.name,self.age)
#定义子类
class Student(Person):
def __init__(self,name,age,score):
super().__init__(name,age)
self.score=score
def info(self):
super().info()
print('学号:',self.score)
stu = Student('张三',21,'1000')
stu.info()
1
2
张三 21
学号: 1000

(2)object类

  • object类
    • object类是所有类的父类,因此所有类都有object类的属性和方法。
    • 内置函数dir()可以查看指定对象所有属性
    • Object有一个__str__()方法,用于返回一个对于“对象的描述”,对应于内置函数str()经常用于print()方法,帮我们查看对象的信息,所以我们经常会对__str__()进行重写
1
2
3
4
5
6
7
8
class Student:
def __init__(self,name,age):
self.name=name
self.age=age
def __str__(self):
return '我的名字是{0},今年{1}岁'.format(self.name,self.age)
stu = Student('张三',21)
print(stu) #默认调用__str__()这样的方法
1
我的名字是张三,今年21岁

3.多态

  • 多态: 提高程序的可扩展性和可维护性
    • 多态就是“具有多种形态”,即便不知道一个变量所引用的对象到底是什么类型,仍然可以通过这个变量调用方法,在运行过程中根据变量所引用对象的类型,动态决定调用哪个对象中的方法
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
class Animal(object):
def eat(self):
print('动物要吃东西')
class Dog(Animal):
def eat(self):
print('狗吃肉')
class Cat(Animal):
def eat(self):
print('猫吃鱼')
class Person(Animal):
def eat(self):
print('人吃五谷杂粮')

def fun(animal):
animal.eat()
fun(Dog())
fun(Cat())
fun(Person())
1
2
3
狗吃肉
猫吃鱼
人吃五谷杂粮

静态语言和动态语言关于多态的区别

  • 静态语言实现多态的三个必要条件
    • 继承
    • 方法重写
    • 父类引用指向子类对象
  • 动态语言的多态崇尚“鸭子类型”,当看到一只鸟走起来像鸭子、游泳起来像鸭子、收起来也像鸭子,那么这只鸟就可以被称为鸭子。在鸭子类型中,不需要关心对象是什么类型,到底是不是鸭子,只关心对象的行为。

特殊方法和特殊属性

名称 描述
特殊属性 __dict__ 获得类对象或实例对象所绑定的所有属性和方法的字典
特殊方法 __len__() 通过重写__len__()方法,让内置函数len()的参数可以是自定义类型
__add__() 通过重写__add__()方法,可使用自定义对象具有“+”功能
__new__() 用于创建对象
__init__() 对创建的对象进行初始化

类的浅拷贝和深拷贝

  • 变量的赋值操作
    • 只是形成两个变量,实际上还是指向同一个对象
  • 浅拷贝
    • Python拷贝一般都是浅拷贝,拷贝时,对象包含的子对象内容不拷贝,因此,源对象与拷贝对象会引用同一个子对象
  • 深拷贝
    • 使用copy模块的deepcopy函数,递归拷贝对象中包含的子对象,源对象和拷贝对象所有的子对象也不相同

十四、模块、包

模块的定义

  • 模块英文为Modules
  • 模块与函数的关系
    • 一个模块中可以包含N多个函数
  • 在Python中一个扩展名为.py的文件就是一个模块
  • 使用模块的好处
    • 方便其他程序和脚本的导入并使用
    • 避免函数名和变量名冲突
    • 提高代码的可维护性
    • 提高代码的可重用性

1.导入模块

1
2
import 模块名称 [as 别名]
from 模块名称 import 函数/变量/类

2.以主程序方式运行

  • 在每个模块的定义中都包括一个记录模块名称的变量__name__,程序可以检查该变量,以确定他们在哪个模块中执行。如果一个模块不是被导入到其他程序中执行,那么它可能在解释器的顶级模块中执行。顶级模块的__name__变量的值为__main__
1
2
if __name__ = '__main__' :
pass

包的定义

  • 包是一个分层次的目录结构,它将一组功能相近的模块组织在一个目录下
  • 作用:
    • 代码规避
    • 避免模块名称冲突
  • 包与目录的区别
    • 包含__init__.py文件的目录称为包
    • 目录里通常不包含__init__.py文件
  • 包的导入
1
import 包名.模块名

常用的内置模块

模块名 描述
sys 与Pthon解释器及其环境操作相关的标准库
time 提供与时间相关的各种函数的标准库
os 提供了访问操作系统服务功能的标准库
calendar 提供与日期相关的各种函数的标准库
urllib 用于读取来自网上(服务器)的数据标准库
json 用于使用JSON序列化和反序列化对象
re 用于在字符串中执行正则表达式匹配和替换
math 提供标准算术运算函数的标准库
decimal 用于进行精确控制运算精度、有效数位和四舍五入操作的十进制运算
logging 提供了灵活的记录事件、错误、警告和调试信息等目录信息的功能

十五、文件的操作

编码格式

  • 常见的编码格式
    • Python的解释器使用的是Unicode(内存)
    • .py文件在磁盘上使用UTF-8存储(外存)

文件的读写

  • 文件的读写俗称“IO操作”
  • 内置函数open()创建文件对象
  • 语法规则
    • file:被创建的文件对象
    • open():创建文件对象的函数
    • filename:要创建或打开的文件名称
    • mode:打开模式默认为只读
    • encoding:默认文本文件中字符的编写格式为gbk
1
file = open(filename [,mode,encoding])

打开文件:

1
2
3
4
5
6
#打开文件   w模式(写模式,文件不存在会新建)
f = open("test.txt","w")

f.write("hello python")

f.close() #关闭文件

读文件

1
2
3
4
5
6
7
#读文件    read方法读取指定的字符,开始时定位在文件头部,每执行一次向后移动指定字符数
f = open("test.txt","r")

print(f.read(5)) #hello
print(f.read(5)) # pyth

f.close()

一次性读取全部文件内容为列表并遍历:

1
2
3
4
5
6
7
8
9
10
11
12
f = open("test1.txt","r")

content = f.readlines() #一次性读取全部文件为列表,每行一个字符串元素

print(content) #['hello python\n', 'hello python\n', 'hello python']

i = 1
for temp in content:
print("%d:%s"%(i,temp))
i += 1

f.close()
1
2
3
4
5
6
7
['hello python--1\n', 'hello python--2\n', 'hello python--3']
1:hello python--1

2:hello python--2

3:hello python--3

1.常用的文件打开模式

打开模式 描述
r 以只读模式打开文件,文件的指针将会放在文件开头
w 以只写模式打开文件,如果文件不存在则创建,如果文件存在,则覆盖原有内容,文件指针在文件的开头
a 以追加模式打开文件,如果文件不存在则创建,文件指针在文件开头,如果文件存在,则在文件末尾追加内容,文件指针在原文件末尾
b 以二进制方式打开文件,不能单独使用,需要与其它模式一起使用,如rb或wb
+ 以读写模式打开文件,不能单独使用,需要与其他模式一起使用,如a+

2.文件对象的常用方法

方法名 说明
read([size]) 从文件中读取size个字节或字符的内容返回。若省略[size],则读取到文件末尾,即一次读取文件所有内容
redline() 从文本中读取一行内容
readlines() 把文本文件中每一行都作为独立的字符串对象,并将这些对象放入列表返回
write(str) 将字符串str内容写入文件
writelines(s_list) 将字符串列表s_list写入文本文件,不添加换行符
seek(offset[,whence]) 把文件指针移动到新的位置,offset表示相对于whence的位置:
offset:为正往结束方向移动,为负往开始方向移动
whence不同的值代表不同含义:
0:从文件头开始计算(默认值)
1:从当前位置开始计算
2:从文件末尾开始计算
tell() 返回文件指针的当前位置
flush() 把缓冲区的内容写入文件,但不关闭文件
close() 把缓冲区的内容写入文件,同时关闭文件,释放文件对象相关资源

3.案例

间隔两秒打印文件一行内容:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
import time
try:
f = open("test1.txt","r")
try:
while True:
content = f.readline()
if len(content) == 0:
break
time.sleep(2)
print(content)
finally:
f.close()
except Exception as result:
print("发生异常")
finally:
print("文件关闭")
1
2
3
4
5
6
hello python--1

hello python--2

hello python--3
文件关闭

案例:复制文件内容到另一文件并捕获可能出现的异常

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
try:
inputfile = open("test1.txt","r",encoding="utf-8")
outputfile = open("copy.txt","a+",encoding="utf-8")
try:
while True:
content = inputfile.readline()
if len(content) == 0:
break
outputfile.write(content)
print("复制完毕")
except Exception as result:
print("写入文件失败")
print(result)
finally:
outputfile.close()
except Exception as result:
print("读取文件失败")
print(result)
finally:
inputfile.close()

with语句(上下文管理器)

  • with语句可以自动管理上下文资源,不论什么原因挑出with块,都能确保文件正常的关闭,以此来达到释放资源的目的
1
2
3
4
5
6
with open('test1.txt','r') as file:
while True:
content = file.readline()
if len(content) == 0:
break
print(content)
1
2
3
4
5
6
hello python--1

hello python--2

hello python--3

目录的操作

  • os模块是Python内置的与操作系统功能和文件系统相关的模块,该模块中的语句的执行结果通常与操作系统有关,在不同的操作系统上运行,得到的结果可能不一样
  • os模块与os.path模块用于对目录或文件进行操作

可以直接调用可执行文件

1
2
3
import os
#打开QQ
os.startfile('C:\Software\Tencent\QQ\Bin\QQScLauncher.exe')

1.os模块操作目录相关函数

函数 说明
getcwd() 返回当前的工作目录
listdir(path) 返回指定路径下的文件和目录信息
mkdir(path[,mode]) 创建目录
makedirs(path1/path2...[,mode]) 创建多级目录
rmdir(path) 删除目录
removedirs(path1/path2......) 删除多级目录
chdir(path) 将path设置为当前工作目录

2.os.path模块操作目录相关函数

函数 说明
abspath(path) 用于获取文件或目录的绝对路径
exists(path) 用于判断文件或目录是否存在,如果存在返回True,否则返回False
join(path,name) 将目录与目录或者文件名拼接起来
splitext() 分离文件名和扩展名
basename(path) 从一个目录中提取文件名
dirname(path) 从一个路径中提取文件路径,不包括文件名
isdir(path) 用于判断是否为路径