Python 03
小知识点的补充
a = 'alex'
b = 'alex'
print(a == b)
==是数值比较
必须得在终端去试is
a = 'alex@'
b = 'alex@'
print(a is b)---->False
print(id(a))--->id是测试对象的内存地址
print(id(b))
is 比较的是内存地址
小数据池:仅存在于str,int中,小数据池存在的意义就是为了节省内存
在一定范围之内的数字或字符串对n个相同的数据只开辟一个空间
int: -5---256
a=100
b=100
c=100
print(id(a),id(b),id(c))内存地址都是同一个
str:
1.不能含有特殊字符
2.单个元素*数字不能超过21
i = 'a'* 20
i1 ='a' *20
print(id(i),id(i1))
i = 'a'* 21
i1 ='a' *21
print(id(i),id(i1))内存地址不同了
编码二
ascii:数字,字母,特殊字符
字节:八位表示一个字节
字符:是你看到的内容的最小组成单位
abc --> a就代表一个字符
中国:中 就表示一个字符
a:0000 1011
unicode:万国码
起初: a :0000 1011 0000 1011
中:0000 1011 0000 1111
升级: a:0000 1011 0000 1011 0000 1011 0000 1011
中:0000 1011 0000 1111 0000 1011 0000 1111
unicode太占内存
utf-8:最少用8位表示一个字符
a:0000 1011
欧洲:0000 1011 0000 1011
亚洲中:0000 1011 0000 1011 0000 1011
gbk:国标,只有中文和英文
a:0000 1011
中:0000 1011 0000 1011 两个字节
gbk和utf-8中的英文都是用的ascii码
1.不同编码之间的二进制是不能互相识别的
2.对于文件的存储及传输不能是unicode的编码。(因为占用内存太多)
编码之间的转化:
python3x
str:在内部中的编码方式是unicode,所以str不能直接用于文件的存储和发送
int
bool
list
dict
tuple
bytes:str有的操作方法bytes都有,bytes内部编码方式是可设定的,但是是非unicode(utf-8,gbk,gb2312..)

字母:
str:表现形式:s1 = 'alex'
内部编码:unicode
bytes:表现形式:s2 = b'alex'
内部编码:非unicode
s1 = 'alex'
b1 = s1.encode('utf-8')
print(b1)
**************************************************
s1 = 'alex'
b1 = b'alex'
print(s1.capitalize())
print(b1.capitalize())
***************************************************************************8
中文:
str:表现形式:s1 = '中国'
内部编码:unicode
bytes:表现形式:b1 = b'\xe4\xb8\xad\xe5\x9b\xbd'(6个字节表示两个中文)
内部编码:非unicode
s1 = '中国'
b1 = s1.encode('utf-8')#转换成bytes类型
print(b1)
bytes和str之间的转换
str ---->bytes 使用encode编码
s1 = 'alex'
b1 = s1.encode('utf-8')
print(b1)
s1 = 'alex'
b2 = s1.encode('gbk')
print(b2)
bytes--->str decode解码,解码默认可以不写(以什么方式编码方式过来的,就用什么方式编码解码回去)
s1 = 'alex'
b1 = s1.encode('utf-8')
print(b1)
s2 = b1.decode('utf-8')#什么都不写是默认是utf-8
print(s2)
s2是str类型
s1 = 'alex'
b2 = s1.encode('gbk')
s3 = b2.decode('gbk')
print(b2)
print(s3)
**************************
utf-8和gbk对于字母来说引用的都是ascii码:例如以下不会报错
s1 = 'alex'
b1 = s1.encode('utf-8')
s2 = b1.decode('gbk')
print(s2)
但是对于中文会报错
s4 = '中国'
b4 = s4.encode('utf-8')
print(b4)
s5 = b4.decode('gbk')
print(s5)
utf-8的bytes类型转化为gbk的bytes类型(非字母)不能转
s4 = '中国'
b4 = s4.encode('utf-8')#utf-8的bytes类型
#转换成gbk的bytes类型
print(b4)
b6 = b4.decode('utf-8').encode('gbk')
print(b6)
集合
1.集合要求它里面的元素是可哈希的,元素不重复、无序。
但是集合本身是不可哈希的
set1 = {}
功能:
1.关系测试
2.去重
set1 = {'alex','wusir','taibai','alex'}
set2 = {'alex','wusir','taibai','alex',[1,2,3]}
print(set1)
print(set2)--->元素是可哈希的才行
列表去重,先变成集合然后在变成列表:
l1 = [1, 1, 2, 2, 3, 4, 4, 5]
print(list(set(l1)))
集合没有改:因为1.无序2.没有索引
增:
1.add
set1 = {'alex', 'wusir', 'ritian', 'egon', 'barry'}
set1.add('文周')
print(set1)--->每次打印顺序都会变
2.update相当于列表的extend
set1 = {'alex', 'wusir', 'ritian', 'egon', 'barry'}
set1.update('abc')
print(set1)
----->
{'ritian', 'alex', 'wusir', 'b', 'barry', 'c', 'egon', 'a'}
删:
pop随机删除
set1 = {'alex', 'wusir', 'ritian', 'egon', 'barry'}
set1.pop( )
print(set1)
remove按照元素去删
set1 = {'alex', 'wusir', 'ritian', 'egon', 'barry'}
set1.remove( 'alex')
set1.remove( 'alex1')元素不存在会报错
print(set1)
clear清空
set1 = {'alex', 'wusir', 'ritian', 'egon', 'barry'}
set1.clear()
print(set1)
----->
set()为了与空字典区分{}
del删除整个set
set1 = {'alex', 'wusir', 'ritian', 'egon', 'barry'}
del set1
print(set1)
查:只能用for循环去查
set1 = {'alex', 'wusir', 'ritian', 'egon', 'barry'}
for i in set1:
print(i)
关系测试:
set1与set2的交集:& intersection
set1 = {1, 2, 3, 4, 5}
set2 = {4, 5, 6, 7, 8}
print(set1 & set2)
print(set1.intersection(set2))
并集 | union
set1 = {1, 2, 3, 4, 5}
set2 = {4, 5, 6, 7, 8}
print(set1 | set2)
print(set1.union(set2))
差集 set1独有的元素就叫差集 - 和indifference
set1 = {1, 2, 3, 4, 5}
set2 = {4, 5, 6, 7, 8}
print(set1 - set2)
print(set2 - set1)
print(set1.difference(set2))
反交集:^ symmetric_difference
set1 = {1, 2, 3, 4, 5}
set2 = {4, 5, 6, 7, 8}
print(set1 ^ set2)
print(set1.symmetric_difference(set2))
子集与超集
子集:
set1 = {1, 2, 3}
set2 = {4, 5, 1, 2, 3}
print(set1 < set2)
print(set1.issubset(set2))
超集:
set1 = {1, 2, 3}
set2 = {4, 5, 1, 2, 3}
print(set2 > set1)
print(set2.issuperset(set1))
集合是可变的数据类型
冻集合:变成不可变的集合
set1 = {1, 2, 3}
print(frozenset(set1))
------>
frozenset({1, 2, 3})
深浅copy
赋值运算共用一个内存地址:
s1 = [1, 2, 3]
s2 = s1
s1.append(666)
print(s1, s2)
----->
[1, 2, 3, 666] [1, 2, 3, 666]

浅copy:
s1 = [1, 2, 3]
s2 = s1.copy()
print(s2)
s1.append(666)
print(s1, s2)
------>
[1, 2, 3]
[1, 2, 3, 666] [1, 2, 3]
***********************************************
s1 = [1, 2, 3, [11,22]]
s2 = s1.copy()
s1[-1].append(666)
print(s1, s2)
print(id(s1), id(s2))
print(id(s1[-1]),id(s2[-1]))
--------->
[1, 2, 3, [11, 22, 666]] [1, 2, 3, [11, 22, 666]]
25172968 25173088
25171608 25171608
浅copy的机制:第一层各自独立,从第二层开始共用一个内存地址

深copy:
引用一个模块
import copy
s1 = [1, 2, 3, [11,22]]
s2 = copy.deepcopy(s1)
s1.append(666)
print(s1, s2)
-------->
[1, 2, 3, [11, 22], 666] [1, 2, 3, [11, 22]]
**********************************************************
import copy
s1 = [1, 2, 3, [11,22]]
s2 = copy.deepcopy(s1)
s1[-1].append(666)
print(s1, s2)
-------->
[1, 2, 3, [11, 22, 666]] [1, 2, 3, [11, 22]]
深copy:无论多少层,都是互相独立的。
切片:
先验证第一层:
s1 = [1, 2, 3, [11,22]]
s2 = s1[:]
s1.append(666)
print(s1, s2)
------>
[1, 2, 3, [11, 22], 666] [1, 2, 3, [11, 22]]
再验证第二层:
s1 = [1, 2, 3, [11,22]]
s2 = s1[:]
s1[-1].append(666)
print(s1, s2)
-------->
[1, 2, 3, [11, 22, 666]] [1, 2, 3, [11, 22, 666]]
所以切片是浅copy。
w和a如果没有原文件,创建一个文件把内容写进去
a如果有原文件在原文件的最后面追加,加一个\换行符会另起一行追加
w如果有原文件,将原文件清空再把内容写进去
with open('log1', encoding = 'utf-8') as f1,\
open('log2', encoding ='utf-8', mode ='w') as f2:
print(f1.read())
f2.write('666666666')
with open('log1', encoding = 'utf-8') as f1:
print(f1.read())
pass
with open('log1', encoding ='utf-8', mode ='w') as f2:
f2.write('66666666')
with open('log1', encoding = 'utf-8') as f1:
print(f1.read())
pass
with open('log1', encoding ='utf-8', mode ='w') as f2:
f2.write('66666666')
with open('log1', encoding = 'utf-8') as f1:
print(f1.read())
f1.close()
pass
with open('log1', encoding ='utf-8', mode ='w') as f2:
f2.write('66666666')
import os#可以删除原文件
with open('file', encoding = 'utf-8') as f1,\#一下子全读出来了
open('file.bak', encoding = 'utf-8', mode ='w') as f2:
old_content = f1.read()#old_content的数据类型是字符串
new_content = old_content.replace('alex','SB')
f2.write(new_content)
os.remove('file')
os.rename('file.bak', 'file')
import os
with open('file', encoding = 'utf-8') as f1,\
open('file.bak', encoding = 'utf-8', mode ='w') as f2:
for line in f1:#读一行改一行
new_line = line.replace('SB','alex')
f2.write(new_line)
#w模式写一行会清空,但是w在for循环中写的动作是个持续性的写的过程,写始终没有停过,直到循环完毕,把所有内容写进去,才叫结束一次写的动作
#写模式一写就清空,但是在一个文件句柄里面可以写多次
os.remove('file')
os.rename('file.bak', 'file')
with open('log1', encoding ='utf-8', mode='w') as f1:
f1.write('111')
f1.write('666')
f1.write('333')
f1.write('222')
a = 'adsfdakfjasdlfj'
count = 0
for i in a:
count += 1
print(count)
l1 = [1, 2, 3, 4, 5, 6]
count = 0
for i in l1:
count += 1
print(count)
重复代码多,可读性差
为了解决这两个问题,引进函数:
a = 'adsfdakfjasdlfj'
print(len(a))
------>引出函数概念:
s = 'adsfdakfjasdlfj'
def my_len():#这一步将函数名读到内存,函数体内内容不管
count = 0
for i in s:
count += 1
print(count)
my_len()#内存会立马进入函数体,执行里面的函数
"""
def 关键字 函数名():
函数体
函数执行,函数名()
函数,以功能为导向。
"""
最好不要在函数体内用print()
s = 'adsfdakfjasdlfj'
def my_len():
count = 0
for i in s:
count += 1
print(my_len())
-------->
None
所以需要返回值return
return:
1.终止函数
def func1():
print(111)
print(222)
return
print(333)
func1()
--------->
111
222
2.给函数的执行者返回值。---->函数名()
def func1():
print(111)
print(222)
return 666
ret = func1()
print(ret)
——————————>
111
222
666
"""
return 或者return None(什么都不写会返回一个None)
return单个值 是什么类型就返回什么类型
return多个值 会将多个值放到一个元组中,将元组返回给函数的执行者
"""
def func1():
return 'alex'
ret = func1()
print(ret,type(ret))
-------->
alex <class 'str'>
***************************************************
def func1():
return 'alex', 666, [1, 2, 3]
ret = func1()
print(ret,type(ret))
------>
('alex', 666, [1, 2, 3]) <class 'tuple'>
**************************************************************
s = 'lkfjsjulkjdgjdsf'
def my_len():
count = 0
for i in s:
count += 1
return count
print(my_len())
函数的传参:
函数的执行里面放的参数叫实参,函数的定义中的参数叫形式参数。
def my_len(argv):#形式参数,形参
count = 0
for i in argv:
count += 1
return count
s = 'lkfjsjulkjdgjdsf'
#mylen(s)#实际参数,实参
print(my_len(s))
********************************************************
def my_len(argv):
count = 0
for i in argv:
count += 1
return count
s = 'lkfjsjulkjdgjdsf'
l1 = [1, 2, 3, 4, 5]
print(my_len(l1))
1.形参角度
位置参数
默认参数
动态参数
位置参数:
def func1(a ,b, c):
print(a, b,c)
func1(1,2,'alex')
默认参数:
def login(name, sex):
with open('register',encoding ='utf-8',mode ='a') as f1:
f1.write('{},{}\n'.format(name,sex))
while True:
name = input('请输入姓名:').strip()
sex = input('请输入性别:').strip()
login(name,sex)
************************************************
为了避免重复一直写男,可以将形参写成默认参数:sex默认为男:
def login(name, sex='男'):#默认参数要在位置参数后面
with open('register',encoding ='utf-8',mode ='a') as f1:
f1.write('{},{}\n'.format(name,sex))
while True:
name = input('请输入姓名:').strip()
if '1' in name:
login(name)
else:
sex = input('请输入性别:').strip()
login(name,sex)
——————————————>
输入的时候前面带1就默认为男
动态参数:*args **kwargs 万能参数
args:所有的位置参数,放在一个元组中
kwargs:所有的关键字参数,放在一个字典中
def func3(*args,**kwargs):#函数定义的时候*代表聚合。
print(args)
print(kwargs)
func3(1,2,3,'alex',c=6,name='wiusir',age=21)
------------->
(1, 2, 3, 'alex')#args所有位置参数,放在一个元组中
{'c': 6, 'name': 'wiusir', 'age': 21}#kwargs所有关键字参数,并放在字典中
args和kwargs也可以用其他字母代替,但约定俗成是这两个。
def func3(*args,**kwargs):
print(args)
print(kwargs)
func3([1,2,3],(22,33))
--------->
([1, 2, 3], (22, 33))
{}
*****************************************************************
def func3(*args,**kwargs):
print(args)
print(kwargs)
func3(*[1,2,3],*(22,33))#函数的执行的时候,*代表打散,相当于变成了func3(1,2,3,22,33)
--------->
(1, 2, 3, 22, 33)
{}
def func3(*args,**kwargs):
print(args)
print(kwargs)
func3(**{'name':'alex'},**{'age':23})
--------->
()
{'name': 'alex', 'age': 23}
形参的顺序:位置参数,*args,默认参数,**kwargs
def func5(a,b,*args,sex='男',**kwargs):
print(a,b)
print(args)
print(sex)
print(kwargs)
****************************************************************************
def func2(*args,a,b):
print(args)
print(a,b)
func2(1,2,3,55,66)
#因为args会接收所有实参传过来的位置参数,导致后面的a,b永远也接收不到值,位置参数要一一对应,形参a,b没有接收到值,所以会报错,所以*args一定要放到位置参数后面
******************************************************
def func2(a,b,sex='man',*args):
print(a,b)
print(sex)
print(args)
func2(1,2,3,55,66)
------->
虽然没有报错但是导致默认参数没有意义,所以要把默认参数放到*args后面
def func2(a,b,*args,sex='man'):
print(a,b)
print(sex)
print(args)
func2(1,2,3,55,66,sex='女')
***************************************************8
def func2(a,b,*args,**kwargs,sex='man'):
print(a,b)
print(sex)
print(args)
print(kwargs)
func2(1,2,3,55,66,sex='女')#sex='女'是关键字参数,会被**kwargs收掉
改为:
def func2(a,b,*args,sex='man',**kwargs):
print(a,b)
print(sex)
print(args)
print(kwargs)
func2(1,2,3,55,66,sex='女',name='alex')
*************************************************
def func2(a,b,*args,sex='man',**kwargs):
print(a,b)
print(sex)
print(args)
print(kwargs)
func2(1,2,3,55,66,age=12,sex='女',name='alex')
-------->
1 2
女
(3, 55, 66)
{'age': 12, 'name': 'alex'}
2.实参角度
位置参数
关键字参数
混合参数
位置参数:按照顺序一一对应
def func1(a,b,c):#形参角度的位置参数必须与实参角度按顺序一一对应
print(a,b,c)
func1(1,2,'alex')#这三个参数叫位置参数
------>
1 2 alex
*****************************************************
def max(a,b):
if a > b:
return a
else:
return b
print(max(10,2))
上面可以用三元运算代替(对于条件简单运算结果简单的)
ret = a if a > b else b
def max(a,b):
ret = a if a > b else b
return ret
print(max(10,2))
*********************************************
如果函数体只有一句话的时候,函数体可以挪到上边:
def max(a,b):return a if a > b else b
print(max(8,99))
关键字传参:一一对应
def func2(a ,b):
print(a, b)
func2(b=2, a=3)#关键字传参不用在乎顺序
混合参数:(位置参数,关键字参数)
关键字参数必须要在位置参数的后面
def func3(a ,b, c, d):
print(a, b,c, d)
func3(1,2,5,d=3)

浙公网安备 33010602011771号