内容回顾
1.python语法—注释
常用的注释方法有四种
1)单行注释 # 注释的内容
2)多行注释 '''
注释的内容
'''
3)多行注释 """
注释的内容
"""
4)自定义注释 选中区域ctrl + ?
2.python语法—变量与常量
变量:可能会常改变的数据
变量:可能不常改变的数据
#多用于给一个数据值定义一个名字
命名规范:
1)名字中只能出现字母、数字、下划线
2)数字不能开头
3)名字不能与python关键字冲突
4)常量通常用大写字母表示
命名风格:
1)下划线:user_name = '张三'
2)驼峰体:
小驼峰:userNameFrom = '张三'
大驼峰:UserNameFrom = '张三'
#一般用了一个风格就不要再出现其他风格
3.python基本数据类型
(1)整数型int
主要就是数字:12、13、14、15
(2)浮点型float
主要就是小数:12.1、12.2、13.3
(3)字符串型str
用引号引起来的都算字符串:’张三’、’adg’、’123′
(4)列表list
1.主要用来存放数据,可以获取单个或整体的数据
name = ['张三','123','run']
#索引取值:
name = ['张三','李四','王五']
print(name[1])#结果:李四
(5)字典dict
1.主要用来存放多个数据,可以获取单个或整体的数据切会有对应的解释
2.数据的形式为:K:V键值对
info = {'姓名':'张三','年龄':'18','爱好':'跑步'}
#字典取值:字典只能用K取值
info = {'姓名':'张三','年龄':'18','爱好':'跑步'}
print(info['姓名'])#结果:张三
(6)布尔值bool
1.主要用来表示事物正确或错误, True / False
2.存储布尔值的名字一般都用 is_名字
(7)元组tuple
1.主要用来存放数据,可以获取单个或整体的数据
2.与列表的区别是元组一般存放的数据都是不允许修改的。
列表: l1=[1,2,3]
l1[0]='99'
print(l1)#结果:99,2,3
元组: t1=(1,2,3)
t1[0]='99'
print(t1)#结果:报错
(8)集合set
1.主要用来去重和关系运算
s1={1,2,3}
4.python基本运算符
(1)算数运算符
1.加减乘除+-*/
2.整除(只要除完后的整数)//、取模(只要除完后的小数)%、幂指数(次方)**
#自增
x = x + 1
x += 1
(2)比较运算符
用来对两个值进行比较,返回的是布尔值
== 等于 #注意:一个等于号是赋值符号
!= 不等于
> 大于
< 小于
>= 大于等于
<= 小于等于
(3)赋值运算符(链式、交叉、解压赋值)
链式赋值:一般是把一个值同时赋值给多个变量名
x = y = z = 10#让xyz都绑定数值10
交叉赋值:让a绑定b的值,b绑定a的值
a,b = b,a #a绑定了b的值 b绑定了a的值
解压赋值:把列表中的多个值依次赋值给多个变量名
l1=['11','12','13']
num1,num2,num3 = l1#输出num1就是11,输出num2就是12
(4)逻辑运算
and 与 、 or 或 、 not 非
and链接的多个条件必须'都成立',结果才为 True
or链接的多个条件'有一个成立',结果就为 True
not是将对的变成错的,错的变成对的
#如果三者混用必须加括号来区分优先级
(5)成员运算
in 在..之内
not in 不在..之内
#字典在做成员运算时只有K会参与运算
(6)身份运算
is 判断的是数据值的内存地址是否一致
== 判断的数据值是否一致(不看地址)
#值相等内存地址不一定相等
#内存地址相等 值一定相等
5.python流程控制
1)顺序结构:从上到下依次执行
2)分支结构:根据条件的不同执行不同代码
3)循环结构:根据条件判断是否一直循环执行该代码
(1)顺序结构
按照代码的先后顺序依次执行
(2)分支结构
根据条件判断是否成立,来决定执行哪个分支
1)单 if分支
if 条件:
条件成立后执行的子代码
#if如果成立则执行if下相关的代码
2)if..else分支
if 条件:
条件成立后执行的子代码
else:
条件不成立执行的子代码
#if如果成立则执行if下的子代码,如果不成立则执行else下的子代码
3)if..elif..else分支
if 条件1:
条件1成立后执行的子代码
elif 条件2:
条件2成立后执行的子代码
else:
以上条件都不成立执行的子代码
#if看作是如果,elif看作是否则如果,else看作是否则
4)if 嵌套
if 条件1:
条件1成立后执行的子代码
if 条件2:
条件2成立后执行的子代码
else:
条件2不成立执行的子代码
else:
条件1不成立执行的子代码
(3)循环结构
while循环、for循环
while循环时根据条件进行循环,当不成立时就会停止
for循环是按照指定次数进行循环
1)while循环
while 条件:
条件成立后执行的子代码(循环体)
1.先判断while的条件是否成立,成立则执行下面的子代码
2.当子代码运行完会再次回到while的判断条件处
3.如果条件还成立,将继续循环执行该子代码
4.当while的条件不成立时,结束循环
while结束循环的两种方式
(一).当循环条件不成立时
创建一个计数器,当计数器的值与while后的条件不成立时将结束循环
(二).在循环体内部添加关键字强制结束
1)while+break
break仅能结束本层循环#内循环与外循环
2)while+continue
continue是结束本次循环,再回到上一个条件判断处重新开始循环
3)while+else
只有当while循环正常结束后才会实行else的代码
1.while循环的嵌套
while 条件:
条件成立后执行的循环体代码
while 条件:
条件成立后执行的循环体代码
就是再 while里再套一个 while循环,用法和单 while一致
2)for循环
1.for 变量名 in 可迭代对象:#字符串 列表 字典 元组 集合
for循环的循环体代码
2.取值操作:列表、字典(只能取出K)、字符串、元组、集合
#整数型、浮点型、布尔值不支持
eg: aa='python'
for i in aa:
print(i)#结果会把python各个字符每个打印一行
print('z')#结果会把'z'执行'python'6个字符的6次
1.for循环的range()用法:
range能快速产能一个包含多个数据值的列表
1)for i in range(5)#打印出0~4的数字
for i in range(3,10)#打印出3~9的数字
for i in range(0,100,25)#0为起始位置,中间是总共有多少数,最后面的间隔数字
6.python数据类型的内置方法
1.内置方法:每隔数据类型自带的功能
2.使用数据类型内置方法时要用句点符:
数据类型.方法名()
3.查看该数据是什么类型可使用 type()
4.数据遵循 增、删、改、查
(1)整型内置方法(int)
整型就是整数,主要用于计算 没有内置方法
1)类型转换:
int(待转换的数据)
print(int('123')) #结果为123 纯数字可以转换
print(int('1a1')) #结果会报错 字符不可以转换
print(int('12.12')) #结果会报错 小数点不可以转换
print(int([1,2,3])) #结果会报错 列表不可以转换,必须是纯数字
2)进制转换:
#十进制转其他进制
print(bin(100)) #结果是0b1100100 十>>二
0b是二进制数的标识
print(oct(100)) #结果是0o144 十>>八
0o是八进制数的标识
print(hex(100)) #结果是0x64 十>>十六
0x是十六进制数的标识
'数字前面没有任何标识 默认就是十进制数'
#其他进制转十进制
#自动识别转换进制数
print(int(0b1100100)) #结果是100
print(int(0o144)) #结果是100
print(int(0x64)) #结果是100
#人为指定转换进制数
print(int('0b1100100',2)) #结果是100
print(int('0o144', 8)) #结果是100
print(int('0x64', 16)) #结果是100
(2)浮点型内置方法(float)
浮点型就是小数 主要用于计算 也没有内置方法
1)类型转换
float(待转换的数据)
print(float('123')) #结果为123.0
print(type(float('123'))) #结果为float
print(float('12.12')) #结果为12.12
print(type(float('12.12'))) #结果为float
print(float('12.12.12')) #结果会报错
2)针对布尔值的特殊方法
print(float(True)) # 1.0
print(float(False)) # 0.0
print(int(True)) # 1
print(int(False)) # 0
(3)字符串内置方法(str)
字符串在调用内置方法时不是改变原数据,而是产生了新的数据。
如果想用修改后的数据需重新绑定一个名字
1)类型转换:#所有的数据类型都可以转换成字符串
eg:
l1={'name': 'jason'}#定义一个字典
l2=str(l1)#把字典转为字符串并赋值给l2
print(type(l2))#查看l2的数据类型 结果是str字符串型
s1 = 'hello 张三'
1)索引取值(单个字符)
print(s1[0])#h
print(s1[5])#为空 原因是索引5对应的是空格 空格占一个索引
print(s1[-1])#三
2)切片取值(多个字符)
print(s1[:]) #打印所有
print(s1[0:3]) #hel 从索引0的位置到索引2的位置
print(s1[-4:-1])#0 张 从索引-3的位置到索引-1的位置
print(s1[-1:-5:-1]) #三张 o 需第三个参数-1来控制方向才可以从右往左切
3)间隔/方向
print(s1[::2])#hlo张 隔一位取一个值
print(s1[0:8:1])#hello 张三
print(s1[0:8:2])#hlo张
print(s1[1:8:1])#ello 张三
4)统计字符串中字符的个数
print(len(s1)) #8 需注意空格也算字符
5)移除字符串首尾指定的字符
eg:
name = ' 张三'
print(name.strip())#张三
print(len(name))#4
'是因为字符串调用内置方法时不是改变原数据,而是产生了新的数据。 如果想要用修改后的数据需重新绑定一个名字'
name1=name.strip()
print(name1)#张三
eg:
name = '$$张三$$'
print(name.strip('$'))#张三 移除左右两边
print(name.lstrip('$'))#张三$$ 只移除左边
print(name.rstrip('$'))#$$张三 只移除右边
案例:用户登录界面当用户输入数据时加了空格
name=input('输入名字:').strip()#让用户输入完直接更改信息并绑定给前面的name
6)按照指定的字符切割字符串:#切割后会成为列表
'当字符串出现了连续的特征符号 就用切割操作'
eg:
xx = '张三|123|run'
xx1 = xx.split('|')
print(xx)#张三|123|run
print(xx1)#['张三','123','run']
xx = '张三|123|run'.split('|')
print(xx)#['张三', '123', 'run']
xx = '张三|123|run'.split('三')
print(xx)#['张','|123|run']
xx = '张三|123|run'
name,pwd,hobby = xx.split('|')#解压赋值让name=张三,pwd=123,hobby=run
xx='张三|123|run'
print(xx.split('|',maxsplit=1))#['张三', '123|run']
#从左往右只切一次
xx='张三|123|run'
print(xx.rsplit('|',maxsplit=1))#['张三|123', 'run']
#从右往左只切一次
7)字符串大小写转换(常见输入验证码时)
lx = 'HeLLo66阿'
print(lx.lower())#hello66阿
'大写转小写'
print(lx.upper())#HELLO66阿
'小写转大写'
print(lx.islower())#False
print('aaa'.islower())#True
'判断字符串中所有字符是否都是小写'
print(lx.isupper())#False
print('AAA'.isupper())True
'判断字符串中所有字符是否都是大写'
eg:创建一个验证码输入界面
yzm = 'CsUp66'#创建一个固定验证码
print('给你的验证码为:%s' % yzm)#给用户显示验证码是什么
yzm1 = (input('请输入验证码:'))#让用户输入验证码
if yzm.lower() == yzm1.lower():#把yzm与yzm1一起改为小写然后对比
print('正确')
else:
print('错误')
8)字符串的格式化输出
方式一:等价于%s 没优势
lx = '我的名字是{},我的年龄是{}'
print(lx.format('张三',18))#我的名字是张三,我的年龄是18
方式二:支持索引取值,可以重复使用
lx = '我的名字是{0},我的年龄是{1}{0}{1}'
print(lx.format('张三',18))#我的名字是张三,我的年龄是18张三18
方式三:支持关键字取值(按K取值),可重复使用
lx = '名字是{name}{name}年龄是{age}'
print(lx.format(name='张三',age=18))#名字是张三张三年龄是18
方法四:最常用!!
name = '张三'
age = 18
print(f'名字是{name}年龄是{age}{age}')#名字是张三年龄是1818
9) 统计字符串中指定字符出现的次数(可单可多)
lx = 'ababdddd'
print(lx.count('a'))#2
print(lx.count('ab'))#2
10)判断字符串的开头或结尾
lx = 'hello my baby'
print(lx.startswith('he'))#True
print(lx.startswith('e'))#False
print(lx.endswith('by'))#True
print(lx.endswith('b'))#False
11)字符串的替换
lx = 'cat cat one one'
print(lx.replace('cat','dog'))#dog dog one one
#从左往右全部替换
lx = 'cat cat one one'
print(lx.replace('cat','dog',1))#dog cat one one
#从左往右替换指定个数
12)字符串的拼接
lx1 = 'hello'
lx2 = 'cat'
print(lx1+lx2)#hellocat
#容易占内存 量少可以用+
print((lx1*2))#hellohello
#把一个字符重复N次
print(''.join(['hello','world','ha']))#helloworldha
print('|'.join(['hello','world','ha']))#hello|world|ha
#量多时建议使用.join 它可以自动优化内存 如果要带变量名仅能带一个
13)判断字符串中是否是纯数字(常用在用户输入密码等)
print('123'.isdigit())#True
print('123a'.isdigit())#False
print(''.isdigit())#False
eg:判断用户输入的是否为纯数字
age=input('你的年龄是:')
if age.isdigit():
age = int(age)
else:
print('必须输入纯数字')
14)查找某个字符对应的索引值
lx = 'hello my baby'
print(lx.index('m'))#6
print(lx.find('m'))#6
print(lx.index('m',0,5))#如果在索引0~索引5之间没有则会报错
print(lx.find('m',0,5))#-1 如果在索引0~索引5之间没有就会返回-1(没有)
15)正文相关方法(把首字母大写)
lx = 'my name is zhangsan'
print(lx.title())#My Name Is Zhangsan
#将所有首字母都大写
print(lx.capitalize())#My name is zhangsan
#将第一个单词首字母大写
(4)列表内置方法(list)
1)类型转换:#能被for循环的数据类型都可以转换成列表
print(list(123)) #整数型不可转换
print(list(123.1)) #浮点型不可转换
print(list(True)) #布尔值不可转换
print(list([1,2,3])) #列表可转换 [1,2,3]
print(list({'name':'张'})) #字典可转换 ['name']
print(list((1,2,3))) #元组可转换 [1,2,3]
print(list({1,2,3})) #集合可转换 [1,2,3]
lx = ['cat','tony','kevin']
1)索引取值
print(lx[0])#cat
print(lx[-1])#kevin
2)切片操作
print(lx[0:2])#['cat', 'tony']
print(lx[:])#['cat', 'tony', 'kevin']
print((lx[-3:-1]))#['cat', 'tony']
3)间隔/方向
print(lx[::2])#['cat', 'kevin']
4)统计列表中数据值的个数
print(len(lx))#3
5)增加数据
5.1)尾部追加数据值 '括号内无论写什么数据类型 都会当作一个数据值追加
lx.append([1,2])#在最后追加数据值
print(lx)#结果为['cat','tony','kevin',[1,2]]
'列表在调内置方法时是在原数据上修改,与字符串相反'
5.2)任意位置插入数据值
lx.insert(0,'插队')#在首位插入数据值
print(lx)#['插队'cat','tony','kevin']
5.3)扩展列表(让两个列表的值放在一个列表中)
eg:
l1=[1,2,3,4]
l2=[5,6]
方式一:
for i in l1:#让i循环打印出l1的值
l2.append(i)#在l2尾部追加i的值
print(l2)#打印l2
方式二:
print(L1+l2)
方式三:推荐使用!(仅支持for循环的数据类型:列表、字典、字符串、元组、集合)
l1.extend(l2)
print(l1)
6)修改数据
eg:
l1=[1,2,3,4]
l1[0]='z' #把l1索引0的值改为'z'
print(l1)#['z',2,3,4]
7)删除数据
7.1)通用删除
del l1[0]#删除l1索引0的数据值
print(l1)#[2,3,4]
7.2)指定删除
l1.remove(1)#在l1中指定删除这个数据值
print(l1)#[2,3,4]
7.3)先取出数据值然后删除
l1.pop()#括号内不写默认是最后一个,0代表第一个,1代表第二个
print(l1)#[1,2,3]
与指定删除不同的是:
pop是把删除的数据提取出来了,remove是彻底不存在了
l1=[1,2,3,4]
a = l1.pop()#把删除的数据赋值给a
print(a)#4
#常用于观战人数中xx退出观战
l1=[1,2,3,4]
a = l1.remove(1)
print(a)#None(没有)
8)查看数据值对应的索引值
print(l1.index(1))#0 l1中1的索引值为0
9)统计某个数据值出现的次数
l1 = [1,1,2,3,4]
print(l1.count(1))#2 列表中1出现的次数
10)排序
l1.sort() #升序
l1.sort(reverse=True) #降序
11)翻转
l1.reverse()
print(l1)#[4,3,2,1,1]
12)比较
a = [99,11]
b = [11,12,13]
print(a>b)#True 列表在比较大小时是按照位置顺序比较,索引0互相比较,99>11,结果就为True
#不同数据类型之间无法比较
#a比A大,因为中间涉及字符编码,a=97 A=65
#中文也各有编码
(5)元组内置方法(tuple)
1)类型转换:#支持for循环的数据类型都可以转为元组
print(tuple(123)) #整数型不可转换
print(tuple(123.1)) #浮点型不可转换
print(tuple(True)) #布尔值不可转换
print(tuple([1,2,3])) #列表可转换 (1,2,3)
print(tuple({'name':'张'})) #字典可转换('name',)
print(tuple((1,2,3))) #元组可转换 (1,2,3)
print(tuple({1,2,3})) #集合可转换 (1,2,3)
t1 = ()#空元组
t1 = (1,)#当元组只有一个数据值时不要忘记加逗号,否则就会变成括号里的数据类型。
#ps:今后遇到可以存储多个数据值的数据类型,如果里面只有一个数据值,都建议加上逗号
t1 = (1,2,3)
1)索引相关操作
print(t1[0])#1
2)统计元组内数据值个数
print(len(t1))#3
3)元组的索引不能改变绑定的地址
eg:
t1 = (1, 2,[3,4])
t1[-1].append(5) #在元组索引-1(最后)的位置添加数据值5 由于最后的数据类型是列表 所以可以改变
print(t1) # (1,2,[3,4,5])
(6)字典内置方法(dict)
字典一般都是直接定义
1).字典取值
info={'name':'zhang','pwd':'123','hobby':'run'}
print(info['usname'])#不推荐使用,当k不存在时会报错
print(info.get('usname'))#推荐使用
print(info.get('usname','不存在'))
#当k不存在时会默认返回None,也可以自己编辑返回的内容。
#k存在时会返回对应的数据值
2)统计字典中键值对的个数
print(len(info))
3)修改字典V的值
inf=['name'] = 'li'
print(info)#{'name':'li','pwd':'123','hobby':'run'}
4)新增键值对
info={'name':'zhang','age':'18'}
info['pwd']=123#当键存在时是修改,键不存在时是新增
print(info)#{'name':'zhang','age':'18','pdw':'123'}
5)删除数据
(1) del info['name'] #删除name键值对
(2) a=info.pop('name')#打印a就是被删除的v值
(3) info.popitem()#随即删除 一般不用
6)快速获取键 值 键值对数据
print(info.keys())#获取字典所有的K值,结构当作列表
#info_keys(['name','pwd','age'])
print(info.values())#获取字典所有的v值,同样当列表
#info_values(['zhang','123','18'])
print(info.items())#获取字典所有的kv键值对数据,组成列表套元组
#info_items([('name','zhang'),('pwd','123'),('age','18')])
7)快速构造字典 给的值默认情况下所有的键都用一个
仅在笔试题中出现过:
dict=dict.fromkeys(['name','pwd'],[])
dict['name'].append('张')
dict['pwd'].append('123')
问:print(dict)出现的结果是什么?
答:{'name':['张','123'],'pwd':['张':'123']}
(7)集合内置方法(set)
支持for循环的 且数据必须是不可变类型
1)去重
s1 = {1,1,2,2,3,3,4,4}
print(s1)#{1,2,3,4}
eg:把一个列表内的名字去重显示
l1=['jason','jason','oscar','tony']
s1=set(l1)#把列表转换成集合
l2=list(s1)#再把刚刚的集合转回列表
print(l2)#['jason','oscar','tony']
2)关系运算
eg:模拟两个人的好友集合
f1 = {'jason', 'tony', 'oscar', 'jerry'}
f2 = {'kevin', 'jerry', 'jason', 'lili'}
(1)求f1和f2的共同好友
print(f1 & f2)#{'jason','jerry'}
(2)求是f1的好友,但不是f2的好友
print(f1 - f2)#{'oscar', 'tony'}
(3)求f1和f2所有的好友(没重复的)
print(f1 | f2)#f1和f2所有的好友(无重复)
(4)求f1和f2各自独有的好友(排除共同好友)
print(f1 ^ f2)
3)父集 子集
eg:
s1 = {1, 2, 3, 4, 5, 6, 7}
s2 = {3, 2, 1}
print(s1 > s2)#判断s1是不是s2的父集 True
#集合在做比较时是依照谁包含谁来判断谁是父谁是子
(8)可变与不可变数据类型
'疑问:为什么字符串调用的内置方法是产生新的值,而列表却是改变自身?'
1.可变数据类型 list列表
值改变(用内置方法来改变),内存地址可不变
#调用内置方法后改变的是自身
l1 = [11, 22, 33]
print(id(l1)) # 1931283911552
l1.append(44) # [11, 22, 33, 44]
print(id(l1)) # 1931283911552
#列表在索引3下可以自由伸缩创建索引4
2.不可变数据类型 str字符 int整型 float浮点
值改变(用内置方法来改变),内存地址肯定变
#调用内置方法后不改变自身,而是产生新的值
s1 = '$hello$'
print(id(s1)) #2623221532
s1 = s1.strip('$')
print(id(s1)) #2852135153
7.python垃圾回收机制
'能自动帮助管理程序运行中产生的垃圾数据'
''''python会自动帮你申请和释放内存空间
别的编程语言需要自己申请或释放''''
策略1.引用计数
当数据值身上的引用计数不为0表示该数据值还有用,不会删除
当数据值身上的引用计数为0,则会被垃圾回收机制回收
name = 'jason' #数据值jason身上的引用计数就是1
name1 = name #数据值jason身上的引用计数就是2
del name1 #数据值jason身上的引用计数变为1
#删除name1(就是解除绑定关系)
'引用计数中有一个循环引用的问题
#循环引用
l1 = ['jason', ]
l2 = ['kevin', ]
l1.append(l2) # 在l1列表后追加l2的数据 引用计数为2
l2.append(l1) # 在l2列表后追加l1的数据 引用计数为2
del l1 # 解除变量名l1与列表的绑定关系 列表引用计数减一
del l2 # 解除变量名l1与列表的绑定关系 列表引用计数减一
策略2.标记清除
专门用来解决循环引用的问题,将内存中程序产生的所有数据值全检查一遍,对存在循环引用(两个数据值循环引用,没有变量名)的打上标记之后一次性清除
#标记清除是每隔一段时间就把所有数据排查一遍资源消耗过大
策略3.分代回收
#为了减轻垃圾回收机制的资源损耗,开发了三代管理,越往下检测频率越低用于节省资源
类似于在学校,差学生每隔5分钟检查一下,中学生每隔15分钟检查一次,好学生每隔45分钟检查一次
区分数据是看该数据值引用计数多与少来判断是否频繁在使用
8.python字符编码
#只有文本文件才有字符编码
#计算机内部存储数据的本质是二进制,也就是计算机只认识0和1
#我们打出的字为什么可以被计算机识别是因为中间有一个转换关系
#转换关系不能随意更改,应有统一标准。字符编码表就是记录了人类的字符与数字的对应关系
字符编码的三个发展阶段:
一:一家独大
由于计算机时美国发明的,所以一开始只有美国有字符编码,用来让计算机识别英文字符
ASCII码:内部用来记录英文字符与数字的对应关系
1字节bytes来存储字符
A~Z 65~90
a~z 97~122
二:群雄割据
各国开始创建自己的字符编码
中国:GBK码,记录中文、英文与数字的对应关系
2字节存储字符 1字节存储英文
韩国:Euc_kr码,记录韩文、英文与数字的对应关系
日本:shift_JIS码,记录日文、英文与数字的对应关系
ps:此时各国计算机文本文件无法直接交互数据,会出现乱码
三:天下一统
万国码(unicode):兼容多个国家字符与数字的对应关系
但是所有字符都是采用2字节起步存储
后来utf家族发布了万国码的优化版>>>utf8
英文1bytes 其他采用3bytes
ps:目前内存使用unicode 硬盘使用utf8
'只有字符串可以参与编码与解码,其他数据类型需先转换成字符才可以'
1.解决乱码的措施:
当初以什么编码存的就用什么编码去解
2.编码与解码
编码:人类的字符>>计算机的数字
将人类的字符按照指定的编码转换成计算机可识别的数字
解码:计算机的数字>>人类的字符
将计算机可识别的数字按照指定的编码转换成人类的字符
s1 = '张三aaaaa'
编码的方式:(只有字符串可以使用)
1.
res = s1.encode('utf8')#不做特殊说明时都用utf8
print(res)# b'/xe5/xbc/xa0/xe4/xb8/x89aaaaa'
'''
b 就是bytes类型,在python中该类型可以直接当作二进制
'''
2.
'当要编码的内容都是纯英文或者数字时可以简写'
print(b'hello my baby')#在字符前加b即可
解码的方式:
res1 = res.decode('utf8')
print(res1)#张三aaa
1.python2默认的编码是ASCII码
如果想用python2使用utf8则需要:
1)文件头(文件最上方)加一句
# coding:utf8
2)每一个字符串前加u
print(u'你好你好')
2.python3默认的编码是utf8码
9.python文件相关操作
1.什么是文件?
文件就是操作系统暴露给用户操作计算机硬盘的快捷方式之一
2.什么是文件操作?
通过编写代码来操作文件的读写
#双击一个软件就是从硬盘加载到内存 写文件后的保存就是将内存中的数据放到硬盘中
(1)用代码操作文件
with open(文件路径,读写模式,字符编码)as 变量名:
子代码运行结束后自动调用close方法(关闭该文件)
eg:
with open(r'a.txt','r',encoding='utf8')as res1:
print(res1.read())#打印读取到的文件内容
#针对文件路径需注意前面要加一个r可以取消路径下/的特殊含义
(2)文件的读写模式
1.r 只读模式 #只能读取内容,不能写
'文件路径存在则读取 / 文件路径不存在则报错'
with open(r'a.txt','r',encoding='utf8')as f:
print(f.read()) #打印出a.txt文件中的内容
2.w 只写模式 #只能写内容,不能读取
'文件路径存在,会先清空内容,然后等待填写新内容 / 文件路径不存在会自动创建该文件'
with open(r'a.txt','w',encoding='utf8')as f:
f.write('123') #清空该文件内容后写入123
3.a 追加模式 #只能在末尾追加新内容,不能读取
'文件路径存在,不会清空内容,会在末尾等待填写新内容 / 文件路径不存在会自动创建该文件'
with open(r'a.txt','a',encoding='utf8')as f:
f.write('123/r')#/r可换行追加新内容
(3)文件操作模式
1.t 文本模式
文件操作的默认模式:(当不写t时默认为文本模式)
r = rt
w = wt
a = at
1.只能操作'文本文件'
2.必须指定encoding参数,不写会采取系统默认编码
3.读写都是以'字符串'为单位
2.b 二进制模式#可以实现数据的拷贝
必须自己指定,不能省略
rb
wb
ab
1.能够操作'所有类型'的文件
2.不用指定encoding参数(因为二进制数不需要编码)
3.读写都是以'bytes字节'为单位
eg:
with open(r'11.jpg', 'rb') as f:
print(f.read())#打印出来的图片就是二进制
'#利用二进制模式实现各种文件的拷贝:'
with open(r'111.jpg','rb')as read_f1,open(r'222.jpg','wb')as write_f2:#用读模式打开一个文件,用写模式打开另一个文件
for i in read_f1: #利用for循环把read_f1中的内容一行一行循环打印出来 '利用for循环是为了不占用较大内存'
write_f2.write(i)#把read_f1循环打印出来的内容写给write_f2
(4)文件操作的多种方式
read() 一次性读取文件内容且光标会停留在文件末尾 继续执行读取则为空
'当文件数据较大时,不推荐一次性读取,涉及多行建议用for循环'
for i in f:
print(i)#结果会把该文件内容一行一行显示出来(区别在于用完第一行自动会清除 不会占用内存)
readline() 一次只读一行内容
readlines() 按行的方式读取所有内容并组织成列表返回#注意换行符
readable() 判断当前文件是否可读#结果为布尔值
writable() 判断当前文件是否可写#结果为布尔值
write() 填写文件内容(注意填写时是先清空后填写)
writelines() 支持填写容器类型(内部可以存放多个数据值的数据类型 列表、字典、元组、集合)
f.writelines(['张/n','李/n','王/n'])#运行后文件就会显示张李王各一行
flush() 将内存中的文件数据立刻刷到硬盘中(类似于保存)
(5)文件光标的移动
1.在文本模式下read(2) 2代表读取几个字符
with open(r'a.txt','r',encoding='utf8')as f:
data = f.read(2)
print(data)
2.在二进制模式下read(3) 3代表读取几个字节
'英文1字节 中文3字节'
with open(r'a.txt','rb')as f:
data = f.read(3)#打印data会出现2进制的字节
print(data.decode('utf8'))#用utf8解码二进制字节
#当文本中都是中文,把读取的字节解码时不是3的倍数时会报错
3.tell()获取光标目前移动了的字节数#不是字符数
with open(r'a.txt','r',encoding='utf8')as f:
data = f.read(3)#当全是汉字文件时,读取3个字符
print(data)#张三说
print(f.tell())#9 因为1个汉字是3字节
代码控制光标移动:
seek(移动的字节数,移动模式)
移动模式:0从文件开头位置开始 1从光标当前位置开始 2从文件末尾开始
eg: 张三说你在讲什么
with open(r'a.txt','r',encoding='utf8')as f:
print(f.read(1))#张 打印该文本读取1个字符
f.seek(6,0)#光标移动6个字节,从文件开头开始移动
print(f.read())#说你在讲什么 打印光标后的所有文本
(6)文件数据修改
"""
机械硬盘存储数据的原理:(与固态硬盘不一样,固态硬盘是算法)
1.数据的修改 其实是覆盖在原来的数据上
2.数据的删除 其实是从占有态变为自由态,数据还能恢复
"""
#运行的程序产生的数据优先存在于内存中
1.代码修改文件内容的方式:
1)覆盖写
先读取文件内容到内存,在内存中完成修改,之后w模式打开该文件写入
eg:
with open(r'a.txt','r',encoding='utf8')as f:
data = f.read()#将文本文件中的内容赋值给data
new_data = data.replace('张三','李四')#将文本文件中的张三替换成李四并赋值给新的变量名
with open(r'a.txt','w',encoding='utf8')as f1:
f1.write(new_data)#在f1文本文件中写入新赋值的变量名内容
"""
优点:是覆盖的模式去修改,硬盘只占用一块空间
缺点:当数据较大时会造成内存溢出
"""
2)重命名
先读取文件内容到内存,在内存中完成修改,之后保存到另一个文件中,再将原文件删除并将新的文件重命名为原文件
eg:
import os
with open(r'a.txt','r',encoding='utf8')as f1,open(r'aa.txt','w',encoding='utf8')as f2:
for i in f1:
f2.write(i.replace('张三', '李四'))
os.remove('a.txt') # 删除文件
os.rename('aa.txt', 'a.txt') # 重命名文件
"""
优点:不会造成内存溢出
缺点:可能临时需要占用硬盘两个地方的空间
"""
10.python函数
(1)函数的本质
"""
提前定义好函数后续可以反复使用
把函数看作是工具
没有函数(没有工具):每次使用都要现场制作
有函数(有工具):提前准备好工具,需要的时候直接拿出来使用
需注意函数必须先定义然后才能使用
"""
提前定义函数(提前准备工具):
def func():
pass
函数的调用(选择工具并使用)
func()
(2)函数的语法结构
def 函数名(参数1,参数2):
'函数注释'
函数体代码
return 返回值
1.def
是定义函数的关键字
2.函数名
与变量名一致 尽量做到见名知意
3.括号
在定义函数的时候函数名后面必须跟括号
4.参数
定义函数括号内可以写参数(可单、可多个) 也可以不写参数
用于接收外界传递给函数体代码内部的数据
简单理解为使用该函数的条件
5.函数注释
类似于说明书 用于介绍函数的主要功能和使用方法
6.函数体代码
整个函数的核心区域 写逻辑代码的地方
7.return
控制函数的返回值,也就是使用完该函数后有没有相应的反馈
(3)函数的返回值
1.函数体代码没有return关键字:默认返回None
2.函数体代码有return关键字:后面不写东西也返回None
3.函数体代码有return关键字:后面写什么就返回什么(数据值就返回数据值,变量名就找到对应的数据值然后返回,变量名对应的函数体就返回函数体)
4.函数体代码有return关键字,且后面写了多个数据值名字 用逗号隔开:默认情况下自动组成元组返回
5.函数体代码遇到return关键字会立刻结束函数体代码的运行(类似break)
(4)函数的参数
形参:函数定义阶段括号内的
实参:函数调用阶段括号内的
#形参相当于变量名 实参相当于数据值
def func(a):
print(a)
func(1)#结果为1
——————————————————
def func(a):
print('张三')
func(1)#结果为张三
位置参数
1.位置形参
在函数定义阶段括号内从左往右依次填写的变量名就叫位置形参
2.位置实参
在函数调用阶段括号内从左往右依次填写的数据值就叫位置实参
eg:
def func(a,b,c):#函数定义阶段括号内的多个变量名就叫位置形参
pass
func(1,2,3)#函数调用阶段括号内的多个数据值就叫位置实参
"""
1.实参可以是数据值也可以是绑定了数据值的变量名
2.位置实参给位置形参传值的时候必须个数一致 不能多也不能少
"""
关键字参数
1.关键字实参
在函数调用阶段括号内以什么等于什么传值称之为关键字实参
"""
1.关键字实参给形参传值,打破了位置的限制
2.关键字实参必须在位置实参的后面
诀窍:无论是形参还是实参,都遵循简单的在前,复杂的在后,同复杂随便.
3.同一个形参在依次调用中只能传一次值(一个形参只能给一个值)
"""
eg:
def func(a,b):
print(a,b)#传给形参什么就打印什么
func(a=1,b=2)#结果为 1 2 关键字实参
func(b=1,a=2)#结果为 2 1 关键字实参 打破了位置限制
func(1,b=2)#结果为 1 2 关键字实参要在位置实参后面
func(a=1,2)#结果会出错 关键字实参在位置实参前会报错
func(1,a=2)#结果会出错 同一个形参在依次调用中只能传一次值
func(a=1, a=2)#结果会出错 同一个形参在依次调用中只能传一次值
默认值参数
1.默认值形参
在函数定义阶段括号内以什么等于什么的形式填写的形参称为默认值形参
eg:写一个学院注册系统
def register(name,age,gender='女'):#在形参定义阶段就可以给性别默认绑定一个女,当用户注册时不录就会默认女,录男就会该为男(你传就用你的,你不传就用默认的)
print(f"""
-------info-------
name:{name}
age:{age}
gender:{gender}
------------------
""")
register('丽丽',18)
register('张三',18,'男')
#1.在函数定义阶段给形参绑定值,后续调用阶段就可以不传值
#2.调用阶段不传值就使用默认的,传了就用新传的值
#ps:定义阶段还需遵循前面的规律(简单在做 复杂在右 同等复杂度随便)
可变长参数
1.可变长形参
可以打破形参与实参的个数限制,随意传值
1)*在形参中的作用:接收多余的位置实参并组成元组赋值给*后面的变量名
#*后面的形参变量名一般用args
eg:定义一个函数,无论接收多少实参都可以执行
def func(*args):#*接收多余的位置实参给后面的args
print(args)
func() #()
func(1) #(1,)
func(1,2) #(1,2)
2)**在形参中的作用:接收多余关键字实参并组成字典赋值给**后面的变量名
#**后面的形参变量名一般用kwargs
eg:定义一个函数,无论接收多少关键字实参都可以执行
def func(**kwargs):#**接收多余的关键字实参给后面的kwargs
print(kwargs)
func() #{}
func(name='a') #{name='a'}
func(name='a',age=18) #{'name':'a','age':18}
3)*与**结合使用
eg:定义一个函数,无论怎么传值都可以执行
def func(*args,**kwargs):
print(args)
print(kwargs)
#位置实参给*,结果是元组() 关键字实参给**,结果是字典{}
func() #() {}
func(1) #(1,) {}
func(1,2) #(1,2) {}
func(a=1) #() {'a':1}
func(a=1,b=2) #() {'a':1,'b':2}
func(1,2,3,a=1,b=2) #(1,2,3) {'a':1,'b':2}
原创文章,作者:sunnyman218,如若转载,请注明出处:https://blog.ytso.com/272845.html