1 python要求顶格书写
2 注释和快捷键
2.1 注释
- 单行注释 #
- 多行注释’‘’
'''
维安大桥
'''
print('多行注释')
2.2 快捷键
快捷键 | 功能 |
---|---|
CTRL+d | 复制当前行到下一行 |
ctrl+/ | 注释 |
shift+enter | 任意位置快速换行,无需到行的末尾 |
ctrl+shift+上箭头 | 将当前行上移 |
3 pep 8规范
- 单行注释#号后面加空格
- 文件最后一行要有空行
- 赋值运算符前后需要空格
- ,后面加空格,前面不需要
- 第一行代码的前面不要有太多空行
- 定义函数时,函数的上下均须预留两个空行
4 变量
数据类型:数字、布尔类型、字符串、list列表、tuple元组、dictionary字典
数字:int、long、float、complex(复数)
布尔:True、False
关键字:type:查看变量类型
print('hello world')
a = 2
b = 2.3
c = False
print(type(a))
print(type(b))
print(type(c))
5 标识符
如变量名等
定义:字母、数字、下划线构成,且数字不能开头
驼峰命名法:第一个单词小写,之后每一个单词的第一个字母大写
如:yourFirstApple
6 关键字
显示关键字
import keyword
print(keyword.kwlist)
7 导包
import keyword # 关键字导包
import random # 随机数导包
8 格式符号
格式符号 | 转换 |
---|---|
%c | 字符 |
%s | 字符串 |
%d | 十进制整数 |
%u | 无符号整数 |
%o | 八进制整数 |
%x | 16进制 |
%f | 浮点数 |
%e | 科学计数法 |
%g | %f和%e的简写 |
如:
name = 'xiaozhi'
id = 123
h = 1.73
print("my name is %s,id is %d,my height is %.2f m" % (name, id, h))
print(f'my name is { name },id is {id},my height is {h} m') # 前面加f
print('hello', end='==')
print('hello', end='\n')
print('happy birther\n to you')
9 输入
关键字:input
注:input输入的都是字符串类型,其他类型需要转换
name = input("please input your name:")
print(f"your name is {name}")
10 类型转换
eval():去掉字符串的引号,转化成原来的类型
str():将数据转化成字符串
a1 = 3.14
a2 = eval('a1')
print(a2, type(a2)) # 去掉引号是a1,存在变量a1
# a3 = eval('a4') 报错,去掉引号是a4,不存在变量a4
a5 = eval('3.14')
print(a5, type(a5))
11 运算符
11.1 算数运算符
符号 | |
---|---|
+ | |
- | |
* | |
/ | |
// | 返回商的整数部分 |
% | 取余数 |
** | 指数 |
11.2 比较运算符
比较运算符 | |
---|---|
1 | == |
2 | < |
3 | > |
4 | <= |
5 | >= |
6 | != |
11.3 逻辑运算符
逻辑运算符 | |||
---|---|---|---|
and | 与 | 两个条件都是真返回True | |
or | 或 | 有一个条件是真就返回True | |
not | 非 | 与条件相反 |
12 if判断语句
score = int(input("请输入你的分数:"))
if score >= 90:
print("优秀")
elif score>100:
print("输入错误!")
elif score<90 and score >=60:
print("良")
else:
print("不及格")
13 debug调试
14 三目运算符
a = 10
b = 5
r = b-a if a < b else a - b
# 中间条件成立是 运行前面,不成立 运行后面
print(r)
15 while
满足条件运行,不满足条件退出。
i = 0
while i<5:
print(i)
i += 1
16 for
for 变量 in 列表或字符串等可迭代对象:
for i in 'happy':
print(i)
for i in range(3):
print(i, end=" ")
print("--------")
for i in range(2, 5):
print(i, end=" ")
print("--------")
for i in range(2, 9, 2):
print(i, end=" ")
print('')
for后面加else,如果不是break跳出循环,就执行else里的内容
for i in range(5):
代码
else:
代码2 当循环运行结束,不是被break运行终止时,运行此行代码
17 break、continue
均用于循环
break:跳出循环,即终止循环
continue:跳过本次循环
for i in range(5):
代码
else:
代码2 当循环运行结束,不是被break运行终止时,运行此行代码
for i in range(3):
print(i, end=' ')
else:
print('end')
print()
for i in range(5):
print(i, end=' ')
if i > 3:
break
else:
print('end')
print()
for i in range(5):
print(i, end=' ')
if i > 3:
continue
else:
print('end')
结果:
0 1 2 end
0 1 2 3 4
0 1 2 3 4 end
18 容器:字符串、列表、元组、字典
18.1 字符串
双引号、单引号、三引号都是字符串,三引号是一块内容
1
# 单引号 双引号相同
a = '123'
b = "123"
print(type(a), a)
print(type(b), b)
# 三引号
c = '''
123
234
345
'''
d = """79
123
456
"""
print(type(c), c)
print(type(d), d)
2
'hello'*3
3
name = '小张'
s = f'我的名字是{name}'
print(s)
18.2 下标(索引)
id = '12233432'
print(id[3])
print(len(id))
18.3 切片
可以获取指定的一段数据
切片语法:[开始位置:结束位置(不包含):步长]
s = 'happy birther'
print(s[3:])
print(s[: 3])
print(s[2:4])
print(s[1::2])
print(s[::-1])
18.4 字符串常用函数
函数名称 | 作用 | |
---|---|---|
find | 检查字符是否在字符串中,有,返回下标,没有返回-1 | str.find(st,start=0,end=len(str)) |
rfind | 从右向左查找 | |
index | 查找,没有会报错,有,返回下标 | |
rindex | 从右向左查找 | |
count | 统计出现的次数 | |
replace | 将str1替换成str2 | str.replace(str1,str2,count=str.count(str1)) |
split | 将str以str1为分隔符进行切割 | str.split(str1,切割次数) |
join | 将str加到迭代器每两个元素之间 | str.join(迭代器) |
a = s.find('h')
print(a)
a = s.find('h', 5, 7)
print(a)
a = s.find('h', 1) # 从下标1处开始查找
print(a)
a = s.find('pp')
print(a)
a = s.count('h')
print(a)
18.4.1 replace
字符串本身不会改变
s = 'aaadddeeeccaa'
print(s)
a = s.replace('a', '3')
print(s)
print(a)
a = s.replace('a', '3', 2)
print(a)
结果:
aaadddeeeccaa
aaadddeeeccaa
333dddeeecc33
33adddeeeccaa
18.4.2 split
默认以空白字符为切割符号,全部切割;
切割之后是列表
s = 'what is your name ?'
r = s.split()
print(s)
print(r)
s = 'saadfgdjk aa sdfgdaafgfhgfxaaghfdh'
r = s.split('aa')
print(s)
print(r)
r = s.split('aa', 2)
print(s)
print(r)
结果:
what is your name ?
['what', 'is', 'your', 'name', '?']
saadfgdjk aa sdfgdaafgfhgfxaaghfdh
['s', 'dfgdjk ', ' sdfgd', 'fgfhgfx', 'ghfdh']
saadfgdjk aa sdfgdaafgfhgfxaaghfdh
['s', 'dfgdjk ', ' sdfgdaafgfhgfxaaghfdh']
18.4.3 join
返回值:一个新的字符串
语法:str.join(迭代器)
目的:将str加入到迭代器中
s1 = '-'.join('hello')
print(s1)
list1 = ['what', 'is', 'your', 'name']
s2 = '-'.join(list1)
print(s2)
结果:
h-e-l-l-o
what-is-your-name
18.4.3 其他不常用函数
字符串所有方法,都不改变原字符串
函数名称 | 作用 | 语法 |
---|---|---|
capitalize | 字符串第一个字符大写 | str.capitalize() |
title | 将字符串每个单词首字母大写 | |
startswitch | 检查字符串是否以str1开头,是,返回True | str.startswitch(str1) |
upper | 字母全部大写 | |
lower | 全部小写 | |
islower | 是否全部小写 | |
endswitch | 是否以str1结尾 | |
center | 居中 | |
ljust | 左对齐 | |
rjust | 右对齐 | |
lstrip | 去掉 左边空格 | |
rstrip | 去掉 右边空格 | |
strip | 去掉左右两边空格 |
s = 'aa dd ssdsfd'
s1 = s.upper()
print(s1)
s1 = s.title()
print(s1)
s1 = s.capitalize()
print(s1)
a = s1.islower()
print(a)
s1 = s1.lower()
print(s1)
结果:
AA DD SSDSFD
Aa Dd Ssdsfd
Aa dd ssdsfd
False
aa dd ssdsfd
2
s = 'wqrfws zxdzcx'
s1 = s.endswith('x')
print(s)
print(s1)
center、ljust、rjust
s = 'asda'
print(s)
s1 = s.center(20)
print('*', s1, '*')
s1 = s.ljust(20)
print('*', s1, '*')
s1 = s.rjust(20)
print('*', s1, '*')
结果:
asda
* asda *
* asda *
* asda *
lstrip、rstrip、strip
s = 'asda'
print(s)
s1 = s.center(20)
print('*', s1, '*')
s2 = s1.lstrip()
print('*', s2, '*')
s2 = s1.rstrip()
print('*', s2, '*')
s2 = s1.strip()
print('*', s2, '*')
结果:
asda
* asda *
* asda *
* asda *
* asda *
18.5 列表
列表可以存放多个数据,且数据类型任意
支持下标和切片操作
注:字符串 不可以通过 下标 修改数据,列表 可以通过 下标 修改数据
1
list1 = [1, 3.4, '3']
print(list1, type(list1))
2
通过下标 修改 列表
list1 = [1, 3.4, '3']
print(list1)
list1[1] = 3
print(list1)
18.5.1 列表遍历
将列表中的数据全部拿出来并打印
list1 = [1, 3.4, '3']
for i in list1:
print(i)
18.5.2 列表添加数据
append尾部添加数据
insert指定下标处添加
extend
列表.extend(迭代器) 将迭代器每一个数据添加到列表末尾
都是在原列表进行添加,不会返回新列表
list1 = ['what', 'is', 'your', 'name']
print(list1)
list1.append('??')
print(list1)
list1.insert(0, '??')
print(list1)
list1.extend('right')
print(list1)
结果:
['what', 'is', 'your', 'name']
['what', 'is', 'your', 'name', '??']
['??', 'what', 'is', 'your', 'name', '??']
['??', 'what', 'is', 'your', 'name', '??', 'r', 'i', 'g', 'h', 't']
18.5.3 列表数据查询
index根据元素返回下标,没有会报错
列表没有find,只有index
count查找元素的个数
in / not in
list1 = ['what', 'is', 'your', 'name']
s = list1.index('is')
print(s)
# s = list1.index('is2') 报错
# print(s)
s = list1.count('your')
print(s)
s = list1.count('yor')
print(s)
n = 'is' in list1
print(n)
n = 'is' not in list1
print(n)
结果:
1
1
0
True
False
18.5.4 列表数据删除
pop默认删除最后一个元素,也可以根据下标删除
del根据下标删除
remove根据元素的之进行删除
用法:
list1 = ['what', 'is', 'your', 'name']
print(list1)
# list1.remove(32) # 没有会报错
list1.remove('is')
print(list1)
print()
list1 = ['what', 'is', 'your', 'name']
print(list1)
# list1.pop(10) 下标不存在,报错
list1.pop() # 默认删除最后一个
print(list1)
list1.pop(0)
print(list1)
print()
list1 = ['what', 'is', 'your', 'name']
print(list1)
del list1[3]
print(list1)
18.5.5 列表数据排序
列表要想排序,那元素的类型必须相同
sort在原列表上排序,从小到大
sorted不在原列表上排序
reverse逆置,在原列表上逆置
用法:
sort
list1 = [1, 7, 3, 10, 5, 6]
print(list1)
list1.sort()
print(list1)
list1.sort(reverse=True) # 倒序
print(list1)
sorted
list1 = [1, 7, 3, 10, 5, 6]
print(list1)
list2 = sorted(list1)
print(list1)
print(list2)
list2 = sorted(list1,reverse=True)
reverse
list1 = [1, 7, 3, 10, 5, 6]
print(list1)
list1.reverse()
print(list1)
18.5.6 列表嵌套
list1 = [1, 7, 3, 10, 5, 6, [1, 2, 3, [1, 2]]]
print(list1)
print(list1[6])
print(list1[6][0])
18.6 元组
注:元组中的元素不可修改
元组和列表相似
t1 = (3)#这是int类型
print(t1, type(t1))
t1 = (3,)#这是元组
print(t1, type(t1))
tuple1 = (1, 2, 3, 4, '3')
print(tuple1, type(tuple1))
18.7 字典
键key
值value
字典没有下标的概念,使用key值访问value值
字典.get(key)如果key值不存在,不会报错
定义字典:
d1 = {}
d2 = dict()
d1 = {'a1': [1, 2, 3], 2: 4}
print(d1)
print(d1['a1'])
print(d1['a1'][1])
print(d1.get(12))
print(d1.get('a1'))
print(d1.get('a3', "不存在返回这个"))
结果:
{'a1': [1, 2, 3], 2: 4}
[1, 2, 3]
2
None
[1, 2, 3]
不存在返回这个
18.7.1 字典添加、修改
注意:int中的1和float中的1.0相同
d1 = {1: 'a', 2: 'b'}
print(d1)
d1[3] = 'c' # 添加
print(d1)
d1[3] = 'd' # 修改
print(d1)
# int 1 float 1.0
print(d1[1])
print(d1[1.0])
结果:
{1: 'a', 2: 'b'}
{1: 'a', 2: 'b', 3: 'c'}
{1: 'a', 2: 'b', 3: 'd'}
a
a
18.7.2 字典删除
del删除指定元素
clear
# del 字典名 直接删除字典
p = {'name': 'xiaoli', 'age': 18, 'id': '1234565'}
print(p)
del p['age']
print(p)
# 字典.pop(key) 删除指定key键值对,并返回 值
p = {'name': 'xiaoli', 'age': 18, 'id': '1234565'}
print(p)
r = p.pop('age')
print(r)
print(p)
# 字典.clear() 清空字典
p.clear()
print(p)
结果:
{'name': 'xiaoli', 'age': 18, 'id': '1234565'}
{'name': 'xiaoli', 'id': '1234565'}
{'name': 'xiaoli', 'age': 18, 'id': '1234565'}
18
{'name': 'xiaoli', 'id': '1234565'}
{}
18.7.3 字典遍历
直接遍历,遍历的是字典的key值
keys:获取所有键值
values:获取所有值
items:获取键值对组成 元组
p = {'name': 'xiaoli', 'age': 18, 'id': '1234565'}
for i in p:
print(i,p[i])
# 获取所有key值
r = p.keys()
# r可以用for遍历
# list(r)可以转换成列表
print(r)
print(list(r))
结果:
name xiaoli
age 18
id 1234565
dict_keys(['name', 'age', 'id'])
['name', 'age', 'id']
items
p = {'name': 'xiaoli', 'age': 18, 'id': '1234565'}
r = p.items()
print(r)
for i in r:
print(i[0], i[1])
print()
for k, v in r:
print(k, v)
print(tuple(r))
结果:
dict_items([('name', 'xiaoli'), ('age', 18), ('id', '1234565')])
name xiaoli
age 18
id 1234565
name xiaoli
age 18
id 1234565
(('name', 'xiaoli'), ('age', 18), ('id', '1234565'))
18.7.4 enumerate()
主要是将元组、列表、字符串的 数据 和 下标 同时列出来
将可迭代序列的数据和下标组合在一起,变成元组
1
st = 'sdfafds'
r = enumerate(st)
print(r)
for k, v in enumerate(st):
print(k, v)
for k in enumerate(st):
print(k)
print(tuple(r))
结果:
<enumerate object at 0x000001EE3510D080>
0 s
1 d
2 f
3 a
4 f
5 d
6 s
(0, 's')
(1, 'd')
(2, 'f')
(3, 'a')
(4, 'f')
(5, 'd')
(6, 's')
((0, 's'), (1, 'd'), (2, 'f'), (3, 'a'), (4, 'f'), (5, 'd'), (6, 's'))
18.7.5 +、*、in、not in
运算符 | |
---|---|
+ | 字符串、列表、元组 |
* | 字符串、列表、元组 |
in | 字符串、列表、元组、字典 |
not in | 字符串、列表、元组、字典 |
字典的比较:比的是key值
19 函数
定义:
def 函数名():
代码
全局变量:global
1
def func():
'''sdfhaif'''
s = '这是函数'
return s
t = func()
print(t)
2
返回多个值
def func(a, b):
c = a+ b
d = a - b
# return [c, d]
# return c, d
# return (c, d)
return {0: c, 1: d}
t = func(13, 4)
print(t)
return后面不屑返回值,默认是none
3
指定实参传递给那个形参
def func(a, b):
print(f'a:{a}')
print(f'b:{b}')
func(1, 2)
func(b=3, a=1)
19.1 函数文档注释
查看注释方法:
- help(函数名)
- 在函数名上右击——go to——declaration or usages
如何给函数写注释:
在函数名下面写三引号注释
def func():
'''sdfhaif'''
print('函数')
help(func)
结果:
func()
sdfhaif
19.2 缺省参数
从左向右缺省给定值
def func(a, b, c=100):
print(f'a:{a}')
print(f'b:{b}')
print(f'c:{c}')
func(1, 2)
func(b=3, a=1)
19.3 不定长参数
参数不固定,多少都可以
在形参前面加*,该形参就变成了不定长的参数元组,可接收所有位置实参
在形参前面加** ,该形参变成不定长的参数字典,可接收所有关键字实参
def func(*args, **kwargs):
print(args)
print(kwargs)
func(1,2,3)
func(a=1,b=2,c=3)
# func(1,2,3,a=3,4)#报错
func(1,2,3,a=3,b=4)
结果:
(1, 2, 3)
{}
()
{'a': 1, 'b': 2, 'c': 3}
(1, 2, 3)
{'a': 3, 'b': 4}
如:求和函数
def func(*args, **kwargs):
print(args)
print(kwargs)
num = 0
for i in args:
num += i
for j in kwargs.values():
num += j
print(f'和:{num}')
func(1, 2, 3)
func(a=1, b=2, c=3)
# func(1,2,3,a=3,4)#报错
func(1, 2, 3, a=3, b=4)
19.4 函数参数完整形式
def func(a, *b, c=10, **d):
print(f'a:{a}')
print(f'b:{b}')
print(f'c:{c}')
print(f'd:{d}')
print()
func(1,2,3,4,5)
func(1,2,3,4,c=20)
func(1,2,3,4,c=20,f=100,h=30,d=10)
结果:
a:1
b:(2, 3, 4, 5)
c:10
d:{}
a:1
b:(2, 3, 4)
c:20
d:{}
a:1
b:(2, 3, 4)
c:20
d:{'f': 100, 'h': 30, 'd': 10}
19.5 拆包
将容器中的数据分给多个变量,数据的个数必须和变量个数相等
a = 1,2,3,4
print(a)
b,c,d,e=a
print(b)
print(c)
print(d)
print(e)
结果:
(1, 2, 3, 4)
1
2
3
4
19.6 引用
python中的一切传递都是引用(相当于地址)
如a=10,是将10所在的地址传递给a,a中存放的是10的地址
a=10
b=a
print(a,b)
print(id(a),id(b))
a=20
print(a,b)
print(id(a),id(b))
结果:
10 10
2201826951696 2201826951696
20 10
2201826952016 2201826951696
id(a)就是变量a的引用
19.7 类型可变与不可变
可变类型:在不改变变量引用的前提下,改变变量中引用的数据
不可变类型:int float bool str tuple(元组数据不可修改)
可变类型:list dict
-list-
list1 = [1, 2, 3]
print(id(list1))
list1.append(4)
print(list1)
print(id(list1))
结果:
1690906849920
[1, 2, 3, 4]
1690906849920
变量中的引用没有发生变化,值却改变了
-tuple-
下面的代码,元组中的值 并没有发生改变,改变的是元组中列表的值
列表是可变类型,值发生改变,引用(地址)不变,即元组中的引用不会发生改变
t = (1, 2, [3, 5])
print(t, id(t))
t[2][1] = 4
print(t, id(t))
结果:
(1, 2, [3, 5]) 1800416286464
(1, 2, [3, 4]) 1800416286464
19.8 引用作函数参数
函数传参传递的是引用
19.9 递归函数
函数本身会调用自己
递归条件:
1.函数调用自己
2.有终止条件
1 阶乘
def func(n):
if n == 1:
return 1
age = n * func(n-1)
return age
a = func(5)
print(a)
19.10 匿名函数
用关键字lambda定义的函数
语法:
lambda 参数列表:表达式
匿名函数不能使用if、for、while,只能编写单行表达式;
匿名函数不需要return,表达式的运行结果就是返回结果
匿名函数可以不返回结果
f1 = lambda: print('123')
f1()
f2 = lambda: 5+6
print(f2())
f3 = lambda a, b: a+b
print(f3(3, 5))
匿名函数可以作为函数的参数使用
为什么要用函数作为参数?
可以使一个函数完成不同的功能
相当于回调函数
def func1(a, b, func):
c = func(a, b)
print(c)
def add(a, b):
return a+b
func1(10, 20, add)
func1(10, 30, lambda a, b: a+b)
func1(10, 30, lambda a, b: a*b)
自定义排序:
按照字符串长度排序
list1 = ['1243', 'sdfsdsfsdf', '345', '124223']
print(list1)
list1.sort(key=lambda x: len(x))
print(list1)
结果:
['1243', 'sdfsdsfsdf', '345', '124223']
['345', '1243', '124223', 'sdfsdsfsdf']
20 列表推导式
目的:为了快速生成列表
list1 = [i for i in range(5)]
list2 = ['h' for i in range(6)]
list3 = [5*i for i in range(6)]
list4 = [(5*i, j) for i in range(2) for j in range(2)]
list5 = [(5*i, j) for i in range(2) for j in range(3)]
print(list1)
print(list2)
print(list3)
print(list4)
print(list5)
结果:
[0, 1, 2, 3, 4]
['h', 'h', 'h', 'h', 'h', 'h']
[0, 5, 10, 15, 20, 25]
[(0, 0), (0, 1), (5, 0), (5, 1)]
[(0, 0), (0, 1), (0, 2), (5, 0), (5, 1), (5, 2)]
21 集合
关键字:set
特点:
- 集合中的数据是不可变类型
- 集合是可变类型
- 集合是无序的,写的顺序和输出的顺序不一样,即没有下标
- 集合中的数据不会重复
无序
s = {1, 2, 3, (1, 2), 'hello', 4, ('123', '234')}
print(s, type(s))
# s1 = {1, 2, 3, [1, 2]} 报错
结果:
{1, 2, 3, (1, 2), 'hello', 4, ('123', '234')} <class 'set'>
集合、列表、元组三者之间可以相互转化
l = [1, 2, 3]
print(set(l))
22 文件
打开文件:
open(file,mode =‘r’,encoding=None)
file是文件名
mode是打开方式,r读,w写,a追加
encoding文件编码格式,一种gbk,一种utf-8
返回值:文件对象
读文件:
文件对象.read()
关闭文件:
文件对象.close()
22.1读文件
注:一次最多读取read(4096)字节
read(n):读取n个字符
f = open('1.txt', 'r')
buf = f.read()
print(buf)
f.close()
读取2个字符:
f = open('1.txt', 'r')
buf = f.read(2)
print(buf)
f.close()
按行读取:
readline():读取单行
readline(n):读取某行前n个字符
readlines():读取所有行
txt文件内容:
f = open('3.txt', 'r')
buf = f.readline()
print(buf)
print()
buf1 = f.readlines()
print(buf1)
f.close()
结果:
happy birther to your!
['happy birther to your!\n', 'happy birther to your!']
去掉换行符:
f = open('3.txt', 'r')
buf1 = f.readlines()
print(buf1)
buf = [i.strip() for i in buf1]
print(buf)
f.close()
结果:
读取大文件:
read是一次读取全部内容的函数,有时候文件会很大
f = open('3.txt', 'r')
while True:
buf = f.readline()
if buf:
print(buf, end='')
else:
break
f.close()
每次读取一行内容并打印,直至读完
22.2 写文件
’w‘模式文件不存在就创建文件
文件中的内容会被清除,并替换成要写入的内容
f = open('2.txt', 'w')
f.write('happy birther to your!\n')
f.write('happy birther to your!\n')
f.write('生日快乐!')
f.close()
没有指明文件编码格式时,windows默认是gbk格式,write以gbk格式写入;而pycharm默认utf-8,用pycharm查看文件时,会出现乱码
编码:使中文汉字和二进制相互转化的规则
22.3 追加文件
直接在文件后面接着写入
f = open('3.txt', 'a')
f.write('happy birther to your!\n')
f.close()
22.4 文件类型
文本文件:txt、py、md;能用记事本打开的文件
二进制文件:具有特殊格式的文件,mp3、mp4、rmvb、png、jpg等
文本文件可以使用文本方式打开,也可以使用二进制方式打开
二进制文件只能使用二进制方式打开
模式 | 解释说明 |
---|---|
r | 只读,指针在开头 |
w | 只写,文件存在就覆盖,没有就创建 |
a | 追加,文件存在,指针在文件末尾;不存在,创建文件 |
rb | 二进制只写 |
wb | |
ab | |
r+ | 读写,指针在文件开头 |
w+ | 读写,文件存在就覆盖,没有就创建 |
a+ | 读写,文件存在,指针放末尾;没有就创建文件 |
rb+ | |
wb+ | |
ab+ |
二进制文件:
f = open('4.txt', 'wb')
f.write('生日快乐'.encode()) # 将str 转化为二进制
f.close()
f = open('4.txt', 'rb')
buf = f.read()
print(buf)
print(buf.decode()) # 解码
f.close()
结果:
23 文件、目录操作
对文件、目录进行操作,需要导入os模块
import os
函数名称 | 作用 |
---|---|
os.rename(老名字,新名字) | 文件重命名 |
os.remove(文件名) | 文件删除 |
os.mkdir(文件名) | 创建文件夹 |
os.getcwd() | 获取当前目录 |
os.chdir(“…/”) | 改变默认目录 |
os.listdir(“./”) | 获取目录列表 |
os.rmdir(文件名) | 删除文件夹(只能删除空的) |
import os
# os.rename('1.txt', 'a.txt')
# os.remove('a.txt')
# os.mkdir('text')
# os.mkdir('text/1')
# os.rmdir('text/1') # 只能删除空目录
buf1 = os.listdir()
print(buf1)
buf = os.getcwd()
print(buf)
# os.chdir('../')返回上一级
os.chdir('text')
buf = os.getcwd()
print(buf)
结果:
24 面向对象
三大特性:封装、继承、多态
类:一组对象的抽象定义
对象:具体的一个东西
属性:
行为:
类的构成:
- 类名
- 属性
- 行为
# 关键字:class
# object:所有类的基类
# 类名:遵循大驼峰命名法:所有单词首字母大写
class Person(object):
def learn(self):
print("数学")
pass
p1 = Person()
p2 = Person()
print(id(p1)) # ....8960
print(id(p2)) # ....8912
# 引用不同
p1.learn()
对象相当于可变类型,修改里面的值,引用不变
class Per(object):
pass
p1 = Per()
p1.name = 'xiaoz'
p3 = p1
print(p1.name, id(p1))
print(p3.name, id(p3))
p3.name = 'zz'
print(p1.name, id(p1))
print(p3.name, id(p3))
p3.age = '13'
print(p1.age, id(p1))
print(p3.age, id(p3))
结果:
p3name值修改了,引用不变
p3添加属性,引用不变
24.1 添加属性
直接添加
不同对象的属性值是没有关联的,相互不影响
class Person(object):
def learn(self):
print("数学")
pass
p1 = Person()
p2 = Person()
# p1 和p2是不同的,因此是相互不影响的
p1.name = '小李' # <——添加属性直接写即可
print(p1.name)
p2.age = '23'
print(p2.age)
24.2 魔法方法
在类中,有一类方法,以两个下划线开头、两个下划线结尾,且满足特定条件下会自动调用,成为魔法方法。
类似c++中的构造函数、析构函数
注:
- 什么时候会自动调用?
- 魔法方法有什么作用?
- 有那些注意事项?
__init__
__str__
__del__
24.2.1 _ init_
调用时机:创建对象之后,会立刻调用;(构造函数)
作用:
- 给对象添加属性,给对象属性赋初值
- 每次创建对象都需要执行的程序,写在init中
- init中有参数时,创建对象时也要传递参数
class Person(object):
def __init__(self):
print("这是人的类")
self.name = '小张'
p1 = Person()
p2 = Person()
print(p1.name)
print(p2.name)
# 每次创建对象,init都会被执行
结果:
带参数的init:
class Person(object):
def __init__(self, name):
print("这是人的类")
self.name = name
# init带参数时,创建对象时也需要带参数
p1 = Person('小李')
p2 = Person('小张')
print(p1.name)
print(p2.name)
# 每次创建对象,init都会被执行
24.2.2 __ str__
调用时机:
- 打印对象时(print),会自动调用str,打印的结果是str方法的返回值
- str(对象)类型转换时,将自定义对象转换为字符串时,会自动调用
- 如果没有自定义str,返回的是对象的引用
注:必须返回一个字符串,只有self一个参数
class Fun(object):
pass
class Person(object):
def __init__(self, name, id):
self.name = name
self.id = id
def __str__(self):
return f'我的名字是{self.name},我的学号是{self.id}'
f1 = Fun()
print(f1)
p1 = Person('小李', 123456)
p2 = Person('小张', 234534)
print(p1)
print(p2)
结果:
24.2.3 __ del__
相当于析构函数
调用时机:
- 对象在内存销毁删除的时候(引用计数为0),会自动调用del
应用场景:
对象被销毁时,需要执行的代码
内存销毁:
- 1 程序代码运行结束,所有对象和变量都会销毁
- 2 使用del,将引用计数变为0,会自动调用
引用计数:python内存管理的一种机制,指一块内存,有多少变量在引用
当一个变量引用一个内存时,引用计数+1
当删除一个变量或这个变量不在引用这块内存时,引用计数-1
当引用计数为0时,这块内存被删除,数据被销毁
i = 1
class Per(object):
def __del__(self):
global i
print(f"我del被调用了{i}")
i += 1
print(1)
p1 = Per()
del p1
p2 = Per()
p3 = Per()
print(2)
结果:
特殊例子:
class Per(object):
def __del__(self):
print("我del被调用了")
p1 = Per()
p3 = p1
print(id(p1))
print(id(p3))
# 引用的是同一块内存,引用计数是2
# 销毁p1后,计数是1,不会调用del
del p1
print('*****程序运行结束******')
结果:
24.2.4 __ repr__
列表中存放对象:
当没有repr方法时,列表中存放的是对象的引用
当有repr方法时,列表中存放的是repr返回的内容
class Per(object):
def __init__(self, name):
self.name = name
class Per1(object):
def __init__(self, name):
self.name = name
def __repr__(self):
return f'my name is {self.name}'
list1 = [Per(123), Per(234)]
print(list1)
list2 = [Per1(123), Per1(234)]
print(list2)
print(list2[0])
结果:
24.2.5 __ mro__
查看类的继承顺序
类名.__mro__返回当前类的调用顺序链
具体参照25.6
24.2.6 __ dict__
可以查看对象的属性信息,类型是字典
key:属性名
value:属性值
对象.__dict__
具体参照26
24.2.7 __ all__
__all__,可以在每个代码文件中定义,类型是元组、列表
作用:from 模块名 import * 此行代码导入的功能是 模块名 中__all__中的内容
25 面向对象-继承
class 类B(类A):
pass
类B继承类A
类A:父类 基类
类B:子类 派生类
class Per(object):
def __init__(self):
print("这是人")
def eye(self):
print("可以看电视")
class Stud(Per):
pass
s = Stud()
s.eye()
25.1 继承分类
单继承:只有一个父类
多继承:有多个父类
多层继承:相当于有爷爷,可以使用所有继承链中的属性和方法
25.2 子类重写父类中的方法
子类的方法和父类中的方法名字相同
重写原因:父类的方法不满足子类,需要重写
class Father(object):
def money(self):
print("much money")
class Me(Father):
def money(self):
print("no money")
f = Father()
f.money()
m = Me()
m.money()
结果:
25.3 子类调用父类的同名方法
三种:
- 1 父类名.方法名()
- 2 super(子类名,self).同名方法的函数名()
- 3 super().同名方法的函数名()
Father.money(self)
super(Me, self).money()
super().money()
例如:
class Father(object):
def money(self):
print("much money")
class Me(Father):
def money(self):
print("no money")
def test(self):
Father.money(self)
super(Me, self).money()
super().money()
m = Me()
m.test()
结果:
25.4 继承中的init
1
class Father(object):
def __init__(self, name):
self.name = name
def __str__(self):
return f'your name is {self.name}'
class Me(Father):
pass
m = Me('liming')
print(m)
结果:
your name is liming
2
子类中添加属性
class Father(object):
def __init__(self, name):
self.name = name
self.age = 30
def __str__(self):
return f'your name is {self.name},age is {self.age}'
class Me(Father):
def __init__(self, name, idd):
# self.name = name 报错
super().__init__(name) #调用父类中的同名函数
self.idd = idd
def __str__(self):
return f'name:{self.name},age:{self.age},id:{self.idd}'
m = Me('liming', 23345)
print(m)
结果:
name:liming,age:30,id:23345
25.5 多继承
有多个父类
子类调用的方法,父类中都存在时,调用第一个父类的方法
class ChinTeacher(object):
def teach(self):
print("chinese")
def other(self):
print("开玩笑")
class EngTeacher(object):
def teach(self):
print('english')
def also(self):
print('no no no')
class Stu(ChinTeacher, EngTeacher):
pass
s = Stu()
s.teach() # 两个父类都有该方法
s.also()
s.other()
结果:
25.6 多继承调用指定父类中的方法
查看继承顺序链:
类名.__mro__返回当前类的调用顺序链
class ChinTeacher(object):
def teach(self):
print("chinese")
def other(self):
print("开玩笑")
class EngTeacher(object):
def teach(self):
print('english')
def also(self):
print('no no no')
class Stu(ChinTeacher, EngTeacher):
pass
s = Stu()
print(Stu.__mro__)
结果:
------指定父类的方法一:直接在子类中重新定义这个函数,并调用父类的函数-----
class ChinTeacher(object):
def teach(self):
print("chinese")
def other(self):
print("开玩笑")
class EngTeacher(object):
def teach(self):
print('english')
def also(self):
print('no no no')
class Stu(ChinTeacher, EngTeacher):
def teach(self):
EngTeacher.teach(self)
s = Stu()
s.teach()
结果:
english
----方法二:用super----
super(类名,self).teach()
按照顺序链,指定类名的下一个 类的方法
继承顺序链:
类ChinTeacher后面是EngTeacher
class Stu(ChinTeacher, EngTeacher):
def teach(self):
super(ChinTeacher, self).teach()
s = Stu()
s.teach()
结果:
english
26 私有权限
在属性名和方法名 前面加两个下划线
不能通过对象访问,只能类内部访问
特点:
- 1 不能通过对象访问,只能在类内访问、使用
- 2 不能被子类继承
注:不是公有权限,就是私有权限
class A(object):
def __init__(self):
self.__name = 'red'
a = A()
print('变之前:', a.__dict__)
a.__name = 'blue'
# 并没有改变私有属性__name的值,只是添加了一个__name公有属性
print('变之后:', a.__dict__)
结果:
相当于添加了一个公有的属性
python私有本质:
修改属性的名字,在创建对象的时候,会自动修改属性名
具体操作在属性前面自动添加_类名
27 私有方法
作用:类内调用,不让外部调用
class A(object):
def __text(self):
print("私有,外部无法调用")
def text1(self):
self.__text()
a = A()
# a.__text() 报错
a.text1()
28 类属性
对象(实例对象):实例属性(每个对象都有一份)
类(类对象):类属性(内存中只有一份)
类属性:在类内,且不在方法内
如:
class A(object):
w = 'good'
def __init__(self, name):
self.name = name
self.age = 10
只有w是类属性
如何区分实例属性和类属性?
看这个属性值修改后,其他是否同步修改
29 类方法
实例方法:类中默认定义的方法, 第一个参数是self,表示实例对象
类方法:使用@classmethod 装饰的方法,第一个参数是cls,代表类对象自己
什么情况定义为实例方法,什么情况定义为类方法?
- 1 如果方法中使用了实例属性,必须定义为实例方法
- 不需要使用实例属性,使用类属性,可以定义为类方法
class A(object):
w = 'good'
def __init__(self, name):
self.name = name
def play(self): # 调用了实例属性,只能是实例方法
print(f'玩{self.name}')
# def weather(self): # 这种形式也行,不如下面这种
# print(f'天气非常{A.w}')
@classmethod
def weather(cls):
print(f'天气非常{cls.w}')
a = A('篮球')
a.play()
A.weather()
结果:
30 静态方法
使用@staticmethod修饰的方法,对参数没有要求,可有可无
什么情况定义静态方法?
方法中不用类属性,也不用实例属性,此时可以定义为静态方法
class A(object):
@staticmethod
def text(): # 若有有参数必须传递实参
print("这是举的一个例子")
A.text()
a = A()
a.text()
结果:
这是举的一个例子
这是举的一个例子
31 多态
同一个名称的方法具有不一样的功能
在使用父类对象的地方,也可以使用子类对象(不同子类对象将会得到不同的结果)
步骤:
- 子类继承父类
- 子类重写父类方法
- 通过对象调用这个方法
class A(object):
def __init__(self, name):
self.name = name
def test(self):
print(f'my name is{self.name}')
class B(A):
def test(self):
print(f'his name is{self.name}')
# ############################################
def func(obj):
obj.test()
a = A('xyz')
b = B('xyz')
func(a)
func(b)
结果:
my name isxyz
his name isxyz
两个对象都有该方法,但执行后的结果不同
32 异常
为了预防可能发生的错误
异常组成:
异常类型:异常具体的描述信息
具体写的方式:
案例一:
try:
num = int(input("num:"))
print(5/num)
# except:
except ZeroDivisionError:
print("error")
结果:
案例二:
try:
num = int(input("num:"))
print(5/num)
# except:
except (ZeroDivisionError, ValueError):
print("error")
案例三:
try:
num = int(input("num:"))
print(5/num)
# except:
except ZeroDivisionError:
print("error")
except ValueError:
print("=====error=====")
32.1 打印异常具体信息
try:
except (异常类型1,异常类型2) as 变量名:
print(变量名)
try:
num = int(input("num:"))
print(5/num)
except ValueError as e:
print("=====error=====")
print(e)
结果:
32.2 捕获所有异常
try:
代码
except:
代码
缺点:不能获取异常的描述信息
try:
代码
except Exception as e:
print(e)
Exception:常见异常类的父类
案例:
try:
num = int(input("num:"))
print(5/num)
except Exception as e:
print(e)
print("--------")
结果:
32.3 异常的完整结构
try:
可能异常的代码
except Exception as e:
出现异常
print(e)
else:
没有出现异常需要执行的代码
finally:
不管异常发生与否,都会执行
32.4 异常的传递
python异常处理的底层机制
异常传递:当出现异常时,异常会向外层传递,直到异常被捕获或者程序报错为止
def func1():
print('===========1')
n = int(input("n:"))
print(5/n)
print('===========2')
def func2():
print('===========3')
func1()
print('===========4')
try:
print('===========5')
func2()
print('===========6')
except Exception as r:
print('===========7')
print(r)
print('===========8')
print('===========9')
结果:
33 模块
查看模块
模块制作:
将python文件命名:满足以字母、数字、下划线命名
模块导入:
一:import 模块名
模块名.方法名()
二:from 模块名 import 方法名1,方法名2,。。。
三:from 模块名 import * 将模块所有功能(变量,函数等)进行导入
# 方法一:
# import random
#
# i = random.randint(1, 10)
# print(i)
# 方法二:
from random import randint
i = randint(1, 10)
print(i)
33.1 as
给模块、模块功能起别名
'''
import 模块名 as 别名
from 模块名 import 功能 as 功能别名
'''
注:导入自己写的模块,要放到同一个目录里
33.2 设置某文件为根目录
文件上右击
查看根目录:
import sys
print(sys.path)
结果:
34 包(package)
把功能相近或相似的模块放到一个目录里,并在目录中定义一个__init__.py文件,则这个目录就是包
导入包:
方法一:import 包名.模块名
方法二:from 包名.模块名 import 功能名
from 包名.模块名 import *
方法三:from 包名 import * ====导入的是__init__.py中的内容
创建包: