Python基础学习
Posted Na_years
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Python基础学习相关的知识,希望对你有一定的参考价值。
1.Python的基本数据类型:
1、int(整数),主要用来进行数学运算,(不可迭代) 2、str(字符串) (可迭代) 3、bool(布尔值) 判断真假 true false 4、list(列表) 存储大量数据 用[]表示 (可迭代) 5、tuple(元组),不可以发生改变 (5可迭代) 6、dict(字典),保存键值对,可以保存大量的数据,无序 7、set(集合),保持大量数据,不可以重复
1.基础数据类型总结
有序无序 | 是否可变 | 是否迭代 | 取值方式 | |
---|---|---|---|---|
int | 有序(不支持索引) | 不可变(可哈希) | 不可迭代 | 直接查看 |
bool | 不可变(可哈希) | 不可迭代 | 直接查看 | |
str | 有序(支持索引) | 不可变(可哈希) | 可迭代 | 通过索引查看 |
tuple | 有序(支持索引) | 不可变(可哈希) | 可迭代 | 通过索引查看 |
list | 有序(支持索引) | 可变(不可哈希) | 可迭代 | 通过索引查看 |
dict | 无序(不支持索引) | 可变(不可哈希) | 可迭代 | 通过键查看 |
set | 无序(不支持索引) | 可变(不可哈希) | 可迭代 | 直接查看 |
##注意事项
-
列表和元组进行乘法时元素都是共用的
1 lst = (1,2,[]) 2 lst1 = lst * 2 3 lst1[-1].append(8) 4 print(lst) 5 print(lst1) 6 >>>(1, 2, [8]) (1, 2, [8], 1, 2, [8])
-
字典和集合
-
大小说的是字典的长度,长度就是键值的个数
-
不能修改键值对的大小,但能修改键对应的值
-
-
集合
-
大小说的是集合的长度,长度就是元素的个数
-
2.字符串
-
字符串在+和*时都是新开辟地址
3.元组
-
V1 = (11, 22, 33) ###tuple
-
数据类型之一,支持索引,支持切片
-
元组是一个有序、可迭代、不可变的数据类型
-
元组 v1 = (11,22,33) ---->叫元组,元组里的一个个值叫元素,以逗号分隔
-
元组不能增删改,只能查
-
()括号中如果只有一个元素,并且没有逗号,那么它不是元组,它与该元素的数据类型一致。
-
长度说的是元素的个数
1 v1 = (11, 11, 22, 33) 2 print(v1.count(33)) >>>>1 3 print(v1.count(11)) >>>>2 4 ###统计元素的个数 5 print(v1.index(33)) >>>>3 6 ###通过元素的名称获取元素的索引
-
面试题
1 # a = (10) 2 print(type(a)) >>><class ‘tuple‘> #当小括号中没有逗号时,数据类型就是括号中数据类型本身 3 # a = ("alex") 4 print(type(a)) >>><class ‘str‘> #当小括号中没有逗号时,数据类型就是括号中数据类型本身 5 # a = ("alex",) 6 print(type(a)) >>><class ‘tuple‘> #这是一个元组 7 # a = () 8 print(type(a)) >>><class ‘tuple‘> #这是元组 9 # a = (1,2,3) 10 print(type(a)) >>><class ‘tuple‘> #这是元组
4.列表
-
V1 = [11, 22, 33] 以逗号分隔每一个内容为元素
-
列表就是一容器
-
可以存储大量不同数据类型的数据
-
列表可以增删改查
-
列表是可变数据类型,可迭代数据类型,有序数据结构
-
列表在进行乘法时,元素都是共用的
##增
+
1 1 lis = [1,2,3] 2 2 lst1 = [4,5,6] 3 3 print((lis + lst1)) 4 4 >>>>[1, 2, 3, 4, 5, 6]
*
1 lst = [1,2,3] 2 print(lst * 5) 3 >>>>[1, 2, 3, 1, 2, 3, 1, 2, 3, 1, 2, 3, 1, 2, 3]
append 追加
1 lst = ["Python学习手册", "核心编程"] 2 lst.append("流畅的Python") 3 print(lst) 4 >>>>[‘Python学习手册‘, ‘核心编程‘, ‘流畅的Python‘]
insert 按照索引插入
1 lst = ["Python学习手册", "核心编程"] 2 lst.insert(0, "Python的学习手册2") 3 print(lst) 4 >>>>[‘Python的学习手册2‘, ‘Python学习手册‘, ‘核心编程‘]
extend 迭代着追加
1 lst = ["Python学习手册", "核心编程"] 2 lst.extend(["老男孩"]) 3 print(lst) >>>>[‘Python学习手册‘, ‘核心编程‘, ‘老男孩‘] 4 lst.extend("老男孩") 5 print(lst) >>>>[‘Python学习手册‘, ‘核心编程‘, ‘老男孩‘, ‘老‘, ‘男‘, ‘孩‘]
##删
pop 按照索引位置删除,默认删除列表中最后一位元素,并且有返回值,返回被删除的元素
1 lst = ["傻屌1", "笨蛋1", "傻狗1"] 2 lst.pop(1) 3 print(lst) 4 >>>>[‘傻屌1‘, ‘傻狗1‘]
remove 指定元素删除,如果有重名元素,默认删除从左数第一个
lst = ["傻屌1", "笨蛋1", "傻狗1"] lst.remove("傻屌1") print(lst) >>>>[‘笨蛋1‘, ‘傻狗1‘]
clear 清空整个列表,不能指定
1 lst = ["傻屌1", "笨蛋1", "傻狗1"] 2 lst.clear() 3 print(lst) 4 >>>>[]
del 删除整个列表,也可按照索引删除 del l1[-1]
1 lst = ["傻屌1", "笨蛋1", "傻狗1"] 2 del lst 3 print(lst) 4 >>>>>NameError: name ‘lst‘ is not defined 5 del lst[2] 6 print(lst) 7 >>>>[‘傻屌1‘, ‘笨蛋1‘]
###for循环删除
1 lst = [11,22,33,44,55] 2 for循环 3 ? 4 ####投机取巧 5 for i in lst: 6 lst.clear() 7 print(lst) 8 ? 9 ####方式一: 10 for i in range(len(lst)): 11 lst.pop(0) 12 print(lst) 13 ? 14 for i in range(len(lst)): 15 lst.pop() 16 print(lst) 17 ? 18 ####方式二: 19 lst = [11,22,33,44,55] 20 lst1 = lst.copy() 21 for i in lst1: 22 lst.remove(i) 23 print(lst)
##改
-
按照索引进行改值
1 lst = ["傻屌1", "笨蛋1", "傻狗1"] 2 lst[2] = "傻帽1" 3 print(lst) 4 >>>>[‘傻屌1‘, ‘笨蛋1‘, ‘傻帽1‘]
-
按照切片进行改值
-
必须是可迭代数据,步长为1时,修改的内容可多可少
-
lst = ["傻屌1", "笨蛋1", "傻狗1", "哈皮1"] lst[1:3] = "杀鬼", "鸟蛋", "狗屎" print(lst) >>>>[‘傻屌1‘, ‘杀鬼‘, ‘鸟蛋‘, ‘狗屎‘, ‘哈皮1‘] lst[0:3] = "杀鬼鸟蛋狗屎" >>>>[‘杀‘, ‘鬼‘, ‘鸟‘, ‘蛋‘, ‘狗‘, ‘屎‘, ‘哈皮1‘] ####################################################################### l1 = [44, 55, 66] l1[2:] = "f","s","asdasd","asdasdasdasd" >>>>[44, 55, ‘f‘, ‘s‘, ‘asdasd‘, ‘asdasdasdasd‘]
-
按照切片(步长)进行改值,所谓的隔值进行更改
-
必须是可迭代数据,步长不为1时,修改的内容得一一对应
-
1 lst = ["傻屌1", "笨蛋1", "傻狗1", "哈皮1","山药","鬼"] 2 lst[0:4:2] = [ "狗屎","朱"] 3 print(lst) 4 >>>>[‘狗屎‘, ‘笨蛋1‘, ‘朱‘, ‘哈皮1‘, ‘山药‘, ‘鬼‘] 5 lst[1:3:2] = [ "狗屎"] 6 >>>>[‘傻屌1‘, ‘狗屎‘, ‘傻狗1‘, ‘哈皮1‘, ‘山药‘, ‘鬼‘] 7 lst[1:4:2] = [ "狗屎","猪"] 8 >>>>[‘傻屌1‘, ‘狗屎‘, ‘傻狗1‘, ‘猪‘, ‘山药‘, ‘鬼‘]
-
反向列表中的元素
lst = [1,2,3,4,6,5] lst.reverse() # 原地修改 print(lst) >>>>[5, 6, 4, 3, 2, 1]
-
排序
1 lst = [1,2,3,4,6,5] 2 lst.sort() # 排序 默认是升序 3 print(lst) 4 >>>>[1, 2, 3, 4, 5, 6]
-
降序
1 lst = [1,2,3,4,6,5] 2 lst.sort(reverse=True) # 降序 3 print(lst) 4 >>>[6, 5, 4, 3, 2, 1]
-
##查
按照索引进行查找(索引正序从0开始,倒序从-1开始)
1 l1 = [44, 55, 66, 22, 22] 2 print(l1[1]) 3 >>>>55
安装切片进行查找
1 l1 = [44, 55, 66, 22, 22] 2 print(l1[0:3]) 3 >>>[44, 55, 66]
例子:
1 li = [1, 3, 2, "a", 4, "b", 5, "c"] 2 print(li[0:3]) >>>>[1, 3, 2] 3 print(li[1:7:2]) >>>>[3, ‘a‘, ‘b‘] 4 print(li[-3:-8:-2]) >>>>[‘b‘, ‘a‘, 3] 5
#列表嵌套
-
lst = ["傻屌1", ["笨蛋1","笨蛋2", ["傻狗1", "傻狗2"],"哈皮1"],"山药","鬼"] print(lst[1][2][1]) >>>>傻狗2
5.while循环
-
break #跳出当前循环,while循环遇到break直接退出不再循环
-
continue #跳出本次循环,继续下次循环(continue就是所在循环体的最后一行代码,循环遇到continue相当于执行到循环底部)
-
在循环体中当遇到break或continue,那么此循环体中break或continue下方的代码都不会被执行
-
while...else语句,while如果被break打断,则不执行else语句
6.if循环
-
单if
-
if...else...
-
if...elif...elif...elif
-
if...elif...elif...else
-
if嵌套
-
if...if...if
-
例子
1 # num = input("儿子,让爸爸看看你考了多少分:") 2 # if int(num) >= 90: 3 # print("A") 4 # elif int(num) >= 80 and int(num) < 90: 5 # print("B") 6 # elif int(num) >= 70 and int(num) < 80: 7 # print("C") 8 # else: 9 # print("太笨了,不像我,呼伦贝尔大草原呀")
-
三元运算
1 num = input("请输入你喜欢的数字:") 2 s = 0 3 if int(num) > 0: 4 for i in num: 5 s = s + int(i) ** 3 6 # print(s) 7 ###三木 8 print("是水仙花" if s == int(num) else "不是")
7.for循环
-
for循环结构
# for i in xxx: # for 关键字 # i 变量名 # in 关键字 # xxx 可迭代对象
-
例子:
1 name = "alex" 2 for i in name: 3 print(i) 4 ? 5 a 6 l 7 e 8 x
-
for i in "": ###为空 print(i) ###不会执行
8.编码
- ASCII 最早的密码本,不支持中文。
#英文 一个字符占用8位
- GBK 国标
#英文 一个字符占用8位(1字节)
#中文 一个字符占用16位(2字节)
- Unicode 万国码 兼容性高
#英文 32位(4字节)
#中文 32位(4字节)
- UTF-8 Unicode的升级版本
#英文 8位(1字节)
#欧洲 16位(2字节)
#亚洲 24位(3字节)
-
单位转换:
1byte = 8bit
1kb = 1024byte
1mb = 1024kb
-
在内存中所有的编码必须是unicode存在,除去bytes
#bytes
-
bytes类型存在的意义:
因为Python字符串类型为str,在内存中用Unicode表示,但是在网络传输过程中或者要存入磁盘时,就需要将str转换成以字节为单位的bytes类型
9.str取值
安装索引:s1[index] 按照切片:s1[start_index:end_index+1] 按照切片步长:s1[start_index:end_index+1:2] 反向按照切片步长:s1[start_index:end_index后延一会:2]
10.哈希数据类型
-
不可变数据类型(可哈希):int str tuple bool
-
可变(不可哈希)的数据类型:list dict set
11.解构
-
一行代码进行数值交换
1 a = 10 2 b = 20 3 a, b = b, a 4 print(a) >>>>>20 5 print(b) >>>>>10 6 ? 7 ? 8 a ,b ,c, d, f = (1, 2, 3, 4, 5) 9 print(a, b, c, d, f) 10 >>>>1 2 3 4 5 11 ? 12 a ,b ,c, d, *f = (1, 2, 3, 4, 5, 6, 7, 8) 13 print(a, b, c, d, f) 14 >>>>>1 2 3 4 [5, 6, 7, 8]
12.字典
-
info = {’k1‘:‘v2‘,‘k2‘,‘v2‘}
k1和k2叫键(keys) v1和v2叫值(values )
-
键:必须是不可变的数据类型(int,str,bool,tuple),唯一的
-
值:任意数据类型,对象
-
查找方便,查询速度快 ,可存储大量的关联型数据
-
可变,无序,不支持索引
-
例子:
1 info = {‘k1‘:‘v2‘, ‘k2‘: ‘v2‘} 2 print(info.keys()) >>>>dict_keys([‘k1‘, ‘k2‘]) 3 print(info.values()) >>>>dict_values([‘v2‘, ‘v2‘]) 4 5 ############ 6 dic = {} 7 print(dict(k=1,v=2,b=4)) 8 print(dict([(1,2),(4,5),(7,8)])) 9 >>> 10 {‘k‘: 1, ‘v‘: 2, ‘b‘: 4} 11 {1: 2, 4: 5, 7: 8} 12 ? 13 ##################### 14 locals = {‘沪‘:‘上海‘, ‘?‘:‘??江‘, ‘鲁‘:‘?东‘} 15 for i in locals: 16 print(i) 17 >>>>沪 黑 鲁
##批量创建键值对
-
fromkeys(seq,values)
-
批量创建键值对,以序列 seq 中元素做字典的键,value 为字典所有键对应的初始值
-
1 dic = dict.fromkeys(‘abc‘, 100) 2 print(dic) >>>>{‘a‘: 100, ‘b‘: 100, ‘c‘: 100} 3 dic1 = dict.fromkeys([1, 2, 3], "qwe") 4 print(dic1) >>>>{1: ‘qwe‘, 2: ‘qwe‘, 3: ‘qwe‘} 5 dic2 = dict.fromkeys([1, 2, 3], []) 6 print(dic2) >>>>{1: [], 2: [], 3: []} 7 dic3 = dict.fromkeys([1, 2, 3], []) 8 dic3[1].append(666) 9 print(dic3)>>>>{1: [666], 2: [666], 3: [666]}
##增
-
通过键直接加
1 dic2 = {‘na‘ : ‘chen‘, ‘age22‘ : ‘32‘} 2 dic2["inttt"] = "lichen" 3 print(dic2) 4 >>>>{‘na‘: ‘chen‘, ‘age22‘: ‘32‘, ‘inttt‘: ‘lichen‘}
-
setdefault()
-
如果键不已经存在于字典中,将会添加键并将值设为默认值None
-
1 dic2 = {‘na‘ : ‘chen‘, ‘age22‘ : ‘32‘} 2 dic2.setdefault(‘na‘,"18") 3 print(dic2) 4 >>>{‘na‘ : ‘chen‘, ‘age22‘ : ‘32‘} ###字典中键存在时不添加,不存在时再进行 5 ? 6 dic2.setdefault(‘na2‘) 7 print(dic2) 8 >>>>{‘na‘: ‘chen‘, ‘age22‘: ‘32‘, ‘na2‘: None} ## 键不存在返回None
##删
-
字典中没有remove
-
pop(),删除指定键值对
-
有返回值,返回被删除的键对应的值
-
dic2 = {‘na‘ : ‘chen‘, ‘age22‘ : ‘32‘} dic2.pop(‘na‘) print(dic2) >>>>{‘age22‘: ‘32‘}
-
clear()
-
清空
-
-
popitem()
-
随机删除,默认删除最后一个
-
dic2 = {‘na‘ : ‘chen‘, ‘age22‘ : ‘32‘} dic2.popitem() print(dic2) >>>>{‘na‘: ‘chen‘}
-
del
-
删除整个字典
-
可指定键进行删除
-
dic2 = {‘na‘ : ‘chen‘, ‘age22‘ : ‘32‘} del dic2[‘na‘] print(dic2) >>>>{‘age22‘: ‘32‘}
###for循环删除字典中的键值对
dic = {"key":1,"key2":2} dic1 = dic.copy() for i in dic1: del dic[i] print(dic) >>>>{}
##改
-
通过键直接改,键不存在时再增加
1 dic2 = {‘na‘ : ‘chen‘, ‘age22‘ : ‘32‘} 2 dic2[‘na‘] = "chenhao" 3 print(dic2) 4 >>>>>>{‘na‘: ‘chenhao‘, ‘age22‘: ‘32‘} 5 dic2[‘name‘] = "ALEX" 6 >>>>>>{‘na‘: ‘chen‘, ‘age22‘: ‘32‘, ‘name‘: ‘ALEX‘}
-
update
-
增加键值对(有则更新,无则添加)
-
1 dic = {‘na‘ : ‘chli‘, ‘age‘ : ‘18‘} 2 dic2 = {‘na‘ : ‘chen‘, ‘age22‘ : ‘32‘} 3 dic.update(dic2) >>>>{‘na‘: ‘chen‘, ‘age‘: ‘18‘, ‘age22‘: ‘32‘} 4 dic2.update(dic) >>>>{‘na‘: ‘chli‘, ‘age22‘: ‘32‘, ‘age‘: ‘18‘} 5 dic.update(na = ‘yyf‘,set = ‘asdasd‘) >>>>{‘na‘: ‘yyf‘, ‘age‘: ‘18‘, ‘set‘: ‘asdasd‘} 6 dic = {} 7 dic.update({"ysue" : "asd"}) 8 print(dic) >>>{‘ysue‘: ‘asd‘}
##查
-
通过键直接查找,查不到会报错
1 dic2 = {‘na‘ : ‘chen‘, ‘age22‘ : ‘32‘} 2 print(dic2[‘na‘]) >>>chen 通过键查找,查不到是报错
-
keys()
-
获取字典索引的键
dic2 = {‘na‘ : ‘chen‘, ‘age22‘ : ‘32‘} print(dic2.keys()) >>>>dict_keys([‘na‘, ‘age22‘])
-
-
values()
-
获取字典所有的值
1 dic2 = {‘na‘ : ‘chen‘, ‘age22‘ : ‘32‘} 2 print(dic2.values()) 3 >>>>>dict_values([‘chen‘, ‘32‘])
-
-
setdefault()
dic2 = {‘na‘ : ‘chen‘, ‘age22‘ : ‘32‘} print(dic2.setdefault(‘na‘)) >>>>chen
-
get()
-
存在是返回值,不存在返回None
1 dic2 = {‘na‘ : ‘chen‘, ‘age22‘ : ‘32‘} 2 print(dic2.get(‘age22‘)) >>>32 3 print(dic2.get(‘name‘)) >>>>None 键不存在时返回None
-
通过键查找,若键存在,返回对应的值,若不存在,可指定返回内容
dic2 = {‘na‘ : ‘chen‘, ‘age22‘ : ‘32‘} print(dic2.get(‘age22‘,‘没有找到‘)) >>>>32 print(dic2.get(‘name‘,‘没有找到‘)) >>>>没有找到 dic2["age22"] = dic2.get("age22") + 1 print(dic2) >>{‘na‘: ‘chen‘, ‘age22‘: 33} ? ? dic = {"A": {"c" : "稷山"}, "B": "唐山"} dic[‘A‘][‘c‘] = dic.get(dic[‘A‘][‘c‘], 1) +1 print(dic) >>>>{‘A‘: {‘c‘: 2}, ‘B‘: ‘唐山‘}
-
##高仿列表
-
可用于for循环
1 dic2 = {‘na‘ : ‘chen‘, ‘age22‘ : ‘32‘} 2 lst = dic2.keys() 3 print(lst) 4 >>>> [‘na‘, ‘age22‘] 5
##字典的嵌套
1 dic = {"1":"饺子", 2 "2":"粥", 3 "3":"面条", 4 "4":"肉", 5 "5":"土", 6 "6":"东南风", 7 "7":"切糕", 8 "8":"烤全羊", 9 "9":"烤骆驼", 10 "10":"锅包肉", 11 "11":"杀猪菜", 12 "12":"乱炖" 13 } 14 while True: 15 choose = input("请输入月份:") 16 if choose in dic: 17 print(dic[choose])
13.运算符
##比较运算符
-
> < >= <= == !=
##算术运算符
-
+ - * /(加减乘除)
//(整除|底板除(向下取整))
** 幂
% 取余 (模)
#### print(5 / 2) # 2.5
#### print(5 // 2) # 2
#### print(2 ** 0) # 1
#### print(5 % 2) # 1
-
##赋值运算符
-
1 #### = 2 #### += 3 #### -= 4 #### *= 5 #### /= 6 #### //= 7 #### **= 8 #### %= 9 #### a = 10 10 #### b = 2 11 #### b += 1 # b = b + 1 12 #### a -= 1 # a = a - 1 13 #### a *= 2 # a = a * 2 14 #### a /= 2 # a = a / 2 15 #### a //= 2 # a = a // 2 16 #### a **= 2 # a = a ** 2 17 #### a %= 2 # a = a % 2
-
##逻辑运算符
-
and ## or ## not
-
优先级:()> not > and > or
-
查找顺序:从左到右
-
练习
1 # 3>2 and 4>2 or True and not False and True 2 # 3>2 and 4>2 or True and True and True 3 # True and True or True and True and True
-
Ture和False进行逻辑运算时:
and:
-
一真一假,就是假
-
同真为真,同假为假
or:
-
一真一假就是真
-
同真为真,同假为假
-
-
and数字进行逻辑运算时:
-
数字不为0时和不为False,and运算选择and后面的内容
-
and运算都为假是选择and前的内容
-
and运算一真一假选择假
-
-
or数字进行逻辑运算时:
-
数字不为0时和不为False,or运算选择or前面的内容
-
or运算都为假时选择or后面的内容
-
or运算一真一假选择真
-
##成员运算符
-
in(在)
-
not in(不在)
1 name = "alex" 2 msg = input(">>>") 3 if name in msg: 4 print(111) 5 else: 6 print(222)
14.格式化输出
#%s-%d-%i
1 name = input("name") 2 age = input("age") 3 msg = """ 4 ------info------ 5 name:%s 6 age:%s 7 -------end------ 8 """ 9 print(msg%(name,int(age),)) 10 ####此处的变量会按照位置来进行一一对应 11
-
%:占位符
-
%s字符串:%s可以填充字符串也可以添加数字
-
%d或i% 整型:必须填充数字
1 name = int(input("请输入你喜欢的数字")) 2 msg = ‘‘‘ 3 NAME = %d 4 ‘‘‘ 5 print(msg%(name))
-
%%转义:变成普通的%
1 num = int(input("请输入你喜欢的数字")) 2 msg = ‘‘‘ 3 NUM = 目前的学习进度是%d%% 4 ‘‘‘ 5 print(msg%(num))
#f-strings
F(f)+ str的形式,在字符串中想替换的位置用{}展位,与format类似,但是用在字符串后面写入替换的内容,而他可以直接识别
1 msg = f‘name:{input("name")},age:{input("age")}‘ 2 print(msg) 3
-
任意表达式
-
字典
1 lst = {‘name‘ : ‘chenhao_li‘ , ‘age‘ :18} 2 msg = f"我是{lst[‘name‘]},年龄{lst[‘age‘]}" 3 print(msg) 4 >>>>我是chenhao_li,年龄18
-
列表
1 lst = [‘chenhao_li‘,18] 2 msg = f"我是{lst[0]},年龄{lst[1]}" 3 print(msg) 4 >>>>我是chenhao_li,年龄18
-
-
表达式
-
用函数完成相应的功能
1 def lst(a,b): 2 return a + b 3 a = 1 4 b = 2 5 print("相加为:" + f"{lst(a,b)}") 6 >>>>相加为:3
-
-
多行f输入
name = ‘barry‘ age = 18 ajd = ‘handsome‘ speaker = f‘我叫{name}.‘ f‘You are {age} years old.‘ print(speaker) >>>>我叫barry.You are 18 years old.
-
if
1 a = 10 2 b = 20 3 msg = f"{a if a < b else b}" 4 print(msg) 5 >>>>10
-
其他
1 print(f"{{73}}") # {73} 2 print(f"{{{73}}}") # {73} 3 print(f"{{{{73}}}}") # {{73}}
-
!,:{};这些标点不能出现在{}里面,会报错
-
使用lambda表达式会出现问题,可将lambda嵌套在圆括号里面解决问题
1 x = 5 2 print(f‘{(lambda x: x*2) (x)}‘) # 10
-
15.赋值与深浅copy
##赋值
-
两个或多个变量名指向同一个内存地址,有一个操作内存地址的值进行改变,其余的变量名在查看的时候都进行更改
##浅copy
-
只copy第一层的元素内存地址,可变的不可变的数据都是公用的
-
多个变量指向同一个内存地址时,如果要修改的内存地址的数据是可变数据类型时,会在原地进行修改(列表、集合)。如果要修改的内存地址的数据是不可变数据类型时,是会重新开辟一个空间(字符串,数字)
-
共用一个值(不同变量的地址指向同一个值)
-
这两个变量指向值的内存地址一样
-
可变数据类型:对其中一个变量的值改变,另外一个变量的值也会改变
-
不可变数据类型:对其中一个的改变,另外一个不变
-
不可变数据类型时
lst1 = [1, 2, 3, [9, 8, 7], 4] lst2 = lst1[:] #浅copy lst1.append(99) print(lst1,lst2) >>>>[1, 2, 3, [9, 8, 7], 4, 99] [1, 2, 3, [9, 8, 7], 4]
-
可变数据类型时
lst1 = [1, 2, 3, [9, 8, 7], 4] lst2 = lst1[:] lst1[-2].append(99) print(lst1,lst2) >>>>[1, 2, 3, [9, 8, 7, 99], 4] [1, 2, 3, [9, 8, 7, 99], 4]
-
##深copy
-
对于不可变的数据,元素是共用的,可变的数据,开辟新的空间,不管嵌套多少层(copy完之后,彼此之间没关系,各过个的日子)
-
两个变量的内存地址不同
-
两个变量各有自己的值,且互不影响
-
对其任意一个变量的值的改变不会影响另外一个
-
不可变数据类型
b = [1 ,2, 3, [99, 88, 77]] b1 = copy.deepcopy(b) b.append(44) print(b,b1) >>>>[1, 2, 3, [99, 88, 77], 44] [1, 2, 3, [99, 88, 77]]
-
不可变数据类型
b = [1 ,2, 3, [99, 88, 77], 22] b1 = copy.deepcopy(b) b[-2].append(44) print(b,b1)
-
##==
-
判断等号两边的值是否相同
a = 10 b = 10 print(a == b) >>>>Ture
##is
-
判断两边的值的内存地址是否相同
a = 10 b = 10 print(a is b) >>>>Ture
16.小数据池和代码块(驻留机制)
驻留机制------节省内存,提高效率
代码块的优先级高于小数据池
##代码块
-
一个py文件、一个函数、一个模块、一个类、终端下的每一行
-
数字:-5 ~ 正无穷
-
所有的代码都是依赖代码块执行
-
乘法时总长度不能超过20
##小数据池
-
数字、字符串、布尔值
-
数字:-5 ~ 256
-
字符串
-
定义和乘法时不能出现中文和特殊字符
-
3.6版本乘法时总长度不能超过20
-
3.7版本乘法总长度不能超过4096
-
17.集合
-
set = {‘太白’, ‘张三‘, ‘李四‘, ‘王五‘}
-
可以去重
1 s5 = {1, 1, 1, 2, 2, 2, 3, 3, 4, 4, 5, 6, 6 } 2 l1 = list(s5) 3 print(l1) ###>>> [1, 2, 3, 4, 5, 6]
-
大小说的是集合的长度
##增
-
add 随意位置插入
1 set = {‘太白‘, ‘张三‘, ‘李四‘, ‘王五‘} 2 set.add(‘xx‘) 3 print(set) 4 >>>>{‘张三‘, ‘李四‘, ‘王五‘, ‘太白‘, ‘xx‘}
-
update 随意位置按元素增加,并去除重复
1 set = {‘太白‘, ‘张三‘, ‘李四‘, ‘王五‘} 2 set.update(‘asdasdasd‘) 3 print(set) 4 >>>>{‘李四‘, ‘王五‘, ‘d‘, ‘张三‘, ‘太白‘, ‘s‘, ‘a‘}
##删
-
remove 指定元素进行删除
1 set = {‘太白‘, ‘张三‘, ‘李四‘, ‘王五‘} 2 set.remove(‘太白‘) 3 print(set) 4 >>>>{‘李四‘, ‘王五‘, ‘张三‘}
-
pop 例:set.pop() 随机删除,有返回值
1 set = {‘太白‘, ‘张三‘, ‘李四‘, ‘王五‘} 2 set.pop() 3 print(set) 4 >>>>{‘张三‘, ‘李四‘, ‘太白‘}
-
clear() 清空
1 a = {1, 2, 3, 4, 5} 2 a.clear() 3 print(a) 4 >>>>set()
##改
-
先删除再添加
1 a = {1, 2, 3, 4, 5} 2 a.remove(2) 3 a.add(333) 4 print(a) 5 >>>>{1, 3, 4, 5, 333}
-
转换数据类型
a = {1, 2, 3, 4, 5} b = list(a) b[2] = 33 print(b) >>>>[1, 2, 33, 4, 5]
##查
-
for 循环
##交-并-差-反交-子-超
1 s1 = {1, 2, 3, 4, 5, 6} 2 s2 = {5, 6, 7, 8, 9, 10} 3 ###交集 4 print(s1 & s2) ###>>>{5, 6} 5 ###并集 6 print(s1 | s2) ###>>>{1, 2, 3, 4, 5, 6, 7, 8, 9, 10} 7 ###差集 8 print(s1 - s2) ###>>>{1, 2, 3, 4} #s1对比s2取独有的 9 print(s2 - s1) ###>>>{8, 9, 10, 7} #s2对比s1取独有的 10 ###反交集 11 print(s1 ^ s2) ###>>>{1, 2, 3, 4, 7, 8, 9, 10} 12 ###子集 13 s3 = {1, 2, 3} 14 s4 = {1, 2, 3, 4, 5} 15 print(s3 < s4) ###>>>True 16 ###超集 17 print(s3 > s4) ###>>>False
18.文件操作
##文件操作模式
-
r 只读
-
w 清空写(可创建文件)
-
a 追加写(可创建文件)
-
rb 只读字节
-
wb 清空写字节
-
ab 追加写字节
-
r+ 读写
-
w+ 清空写读
-
a+ 追加写读
##文件操作步骤
1 f = open("文件名字或文件路径",mode="操作模式",encoding="编码")
##转义
-
"C:user" 用两个 转义一个
-
r"C:user" 用 r 代表转义 (推荐使用)
1 f = open(r"C:Python_26day07萝莉.txt",mode="r",encoding="utf-8")
##读操作( r , rb)
-
read() 全读
-
read(3) r 模式是三个字符,rb 模式是三个字节
-
readline() 读取一行,默认带一个
-
readlines() 读取所有,存储在列表中
-
for i in f: 文件句柄可以迭代,一行一行读取
##清空写( w , wb)
-
有文件时清空文件,没文件时创建文件
-
打开文件时清空文件内容
-
写入内容
1 def lst(name,sex,age,work): 2 mingdan = (f"姓名:{name},性别:{sex},年龄:{age},学历:{work}") 3 with open("student_msg.txt","a",encoding="utf-8") as f: 4 f.write(" "+mingdan) 5 lst("lichenhao","nan",18,"IT")
##追加写( a,ab)
-
没文件时创建文件
-
永远在文件的末尾添加内容
1 f = open("F:学习python-lch作业day08l1.txt","a",encoding="utf-8") 2 f.seek(0,0) 3 print(f.tell()) 4 f.write("嘿嘿我是李晨浩sb") 5 ####在已有的内容后面进行追加 6
##“+”操作
-
r+ 读写 覆盖内容
1 # f = open("test","r+",encoding="utf-8") 2 # a = f.read() 3 # print(a) 4 # f.write("这是读写") 5 #####此处就是先读 之后在写之前清空 6 7 8 9 10 11 12 13 14 # f = open("test","r+",encoding="utf-8") 15 # f.write("这是读写啊") 16 # a = f.read() 17 # print(a) 18 #####此处就是先清空再写 之后再读
-
w+ 清空写读
# f = open("test","w+",encoding="utf-8") # f.write("哈哈哈") # f.seek(0,0) # 移动光标 移动到文件的头部 # print(f.read()) #####先写 再读
-
a+ 追加写读(文件不存在时,实时显示)
f = open("F:学习python-lch作业day08l1.txt","a+",encoding="utf-8")
f.write("asdasd嘿sss嘿")
# f.seek(0,0) # 移动光标 移动到文件的头部
print(f.read())
#####直接在已有的内容后面追加
##光标seek()
-
seek(0,0) 移动到文件头部
-
seek(0,1) 移动到光标当前位置(没用)
-
seek(0,2) 移动到末尾
-
seek(3) 按照字节移动,根据不同编码决定移动字节大小
-
tell() 查看光标,返回的是字节
##with open
-
自动关闭文件
-
可以操作多个文件
-
as 起别名
with open("l1.txt","r",encoding="gbk") as f,
open("l2.txt","r",encoding="utf-8")as f1:
print(f.read())
print(f1.read())
##os
-
与操作员系统做交互
export os
os.rename("test","test2") 将test改名为test2
##注意事项:
-
在不移动光标的情况下,文件中的内容只能读取一次
-
a和w可以创建文件
-
写的类型必须是字符串
-
w写的时候想加换行符" "必须加引号再加上要写的内容
f.write(" "+mingdan)
-
f.flush() 刷新
-
f.close() 关闭文件
19.迭代器
#迭代器
-
方法一:
lst = [1,2,3,4]
l = lst.__iter__() #l是迭代器
print(l.__next__())
print(l.__next__())
print(l.__next__())
print(l.__next__())
>>>1
2
3
4
-
方法二:(推荐使用)
lst = [1,2,3,4]
l = iter(lst) #l是迭代器
print(next(l))
print(next(l))
print(next(l))
print(next(l))
>>>>1
2
3
4
-
for循环支持直接循环迭代器
lst = [1,2,3,4]
l = iter(lst)
for i in l:
print(i)
#for循环本质
-
for循环就是一个迭代器(for循环本质)
s = "alex"
s1 = s.__iter__() #将数据转换成迭代器
while 1: #通过死循环不断调用
try:
print(s1.__next__())
except StopIteration: #捕获异常,使之不会抛出异常
break
>>> a
l
e
#可迭代对象和迭代器:
-
可迭代对象(str list tuple)
-
迭代器也是一个可迭代对象
-
具有iter()方法的就是一个可迭代对象
-
优点:1.使用灵活(每个可迭代对象都有自己的方法)
2.能够直接查看元素的个数
-
缺点:1.占内存
-
当内存大,数据量比较少时,建议使用可迭代对象
-
-
迭代器(文件句柄就是一个迭代器)
-
可next()和iter()的就是一个迭代器
-
优点:1.节省内存
-
缺点:1.只能一个方向执行
2.一次性的
3.不能灵活操作,不能直接查看元素的个数
-
内存小,数据量巨大时,建议使用迭代器
-
#时间、空间
-
时间换空间:迭代器、生成器
-
空间换时间:可迭代对象,使用大量的空间节省时间
?
20.生成器
-
生成器本身就是一个迭代器,迭代器不一定是生成器
-
惰性机制
-
迭代器都是Python给你提供的已经写好的工具或者通过数据转化得来的,(比如文件句柄,iter([1,2,3])。生成器是需要我们自己用python代码构建的工具
#基于函数实现的生成器
-
函数体中存在yield就是定义一个生成器
def func()
print(1)
yelid 5
print(func()) ##函数体中存在yelid就是生成一个生成器
##print打印的是一个生成器对象的内存地址
-
生成器的使用 (next和yelid一一对应)
方法一:
def func():
yield 1 #记录执行位置
yield 2
yield 3
g = func() #获取生成器的内存地址
print(next(g)) #获取值
print(next(g)) #获取值
print(next(g)) #获取值
方法二:
def func():
yield 1 #记录执行位置
yield 2
yield 3
g = func() #获取生成器的内存地址
print(next(g)) #获取值
print(next(g)) #获取值
print(next(g)) #获取值
g1 = func()
print(next(g1)) #重头取值
print(next(g1)) #取值
>>>1
2
3
1
2
方法三:函数嵌套
def func():
def foo():
print(1)
yield foo
g = func().__next__() ##g就是foo的内存地址
print(g(),type(g)) ##g() == foo()
>>>1
None <class ‘function‘>
?
方法四:列表
def func():
yield [1,2,3,4,5,6]
print(func().__next__(),type(func().__next__()))
>>>>[1, 2, 3, 4, 5, 6] <class ‘list‘>
方法五:字典
def func():
yield {"name" : 123}
print(func().__next__(),type(func().__next__()))
>>>{‘name‘: 123} <class ‘dict‘>
方法六:返回多个
def func():
yield 1,2,3,4,5
print(next(func()))
>>>>(1, 2, 3, 4, 5)
方法七:yield from
def func():
yield from [1,2,3,4,5]
g = func()
print(next(g))
print(next(g))
print(next(g))
print(next(g))
print(next(g))
##
#生成器和迭代器区别:
-
迭代器:文件句柄,通过数据转换,Python自带提供
-
生成器:程序员自己实现
#生成器和函数区别
-
函数是return value ,生成器是yield value 并且能够标记或者记住yield执行的位置,以便下次执行时从标记点恢复执行,
-
yield是函数转换成生成器,但是生成器又是一个迭代器
#时间、空间
-
空间还时间
?
-
时间换空间
def func():
for i in range(1,50001):
yield i
g = func()
print(next(g))
print(next(g))
print(next(g))
print(next(g))
#区分迭代器和生成器
-
看内存地址(推荐)
-
看send()方法
def func()
yield 1
g = func()
print(g.send()) ###有send就是生成器
#迭代器和生成器的优缺点
-
优点:1、节省空间
-
缺点:1、不能直接使用元素
2、不能直接查看元素
3、使用不灵活
4、稍微消耗时间
5、一次性的, 不能逆行
#yield功能
-
yield
-
能返回多个,以元组的形式存储
-
能返回各种数据类型(Ptyhon的对象)
-
能够写多个并且都能执行
-
能够记录执行位置
-
后边不写内容 默认返回None
-
能够暂停生成器的运行
-
yield都是将数据一次性返回
-
#yield from 和 yield区别
-
yield
-
yield是将数据整个返回
-
-
yield from
-
将可迭代对象逐个返回
-
#表达式(推导式)实现生成器
-
简化代码,提高逼格,提高可读性
-
生成一些有规律的数据,生成的数据较大时建议使用生成器推导式
-
推导式最多建议使用三层
#生成器推导式
-
普通模式
g = (i for i in range(3))
print(next(g)) >>>0
print(next(g)) >>>1
print(next(g)) >>>2
-
筛选模式
g = (i for i in range(3) if i+1 == 2)
print(next(g))
>>>1
#列表推导式
-
普通循环
print([i for i in range(1,6)]) >>>[1,2,3,4,5]
print([i for i in range(1,6,2)]) >>>[1,3,4]
print([f"Py{i}期" for i in range(1,4)])
>>>[‘Py1期‘, ‘Py2期‘, ‘Py3期‘]
-
筛选模式
print([i for i in range(1,10) if i > 5])
>>>[6, 7, 8, 9]
print([i+j for i in range(2) for j in range(2)]) # 推导式最多建议使用三层
>>>[0, 1, 1, 2]
#字典推导式
-
普通模式
print({i:i+1 for i in range(3)})
>>>{0: 1, 1: 2, 2: 3}
-
筛选模式
print({i:i+1 for i in range(3) if i >1})
>>>{2: 3}
#集合推导式
-
普通模式
print({i for i in range(3)})
>>>{0,1,2}
-
筛选模式
print({i for i in range(3) if i >0}) >>>{1,2}
print({i for i in range(3) if i >2}) >>>set{}
#其他
names = [[‘Tom‘, ‘Billy‘, ‘Jefferson‘, ],[‘Alice‘, ‘Jill‘, ‘Ana‘, ‘Wendy‘]]
print([em for i in names for em in i if "e" in em]) #查找有e的名字
>>>[‘Jefferson‘, ‘Alice‘, ‘Wendy‘]
print([em for i in names for em in i if em.count("e")>=2]) #查找名字中带e超过两个的
>>>[‘Jefferson‘]
multiples = [i for i in range(20) if i % 3 == 0]
print(multiples) >>>[0, 3, 6, 9, 12, 15, 18]
multiples = [i for i in range(20) if i % 3 is 0]
print(multiples) >>>[0, 3, 6, 9, 12, 15, 18]
21.闭包
-
闭包的定义
-
在嵌套函数中,使用非全局变量(且不适用本层变量)
-
将嵌套函数返回
-
-
作用:保持数据安全性,干净性
def func():
a = 10 # 自由变量
def foo():
print(a)
return foo
f = func()
print(f.__closure__) # 验证是否是闭包
print(f.__code__.co_freevars) # 查看自由变量
print(f.__code__.co_varnames) # 查看局部变量
>>>
(<cell at 0x0000024C254B9048: list object at 0x0000024C25365248>,)
(‘lst‘,)
(‘price‘, ‘arg‘)
-
没有将嵌套的函数返回也是一个闭包,但这个闭包不是一个可使用的闭包
def func():
a = 10
def foo():
print(a)
func()
-
闭包的应用场景
-
装饰器
-
防止数据被误改动
-
-
实例(求几次的执行函数的平均值)
def buy_car():
lst = []
def func(price): # price = 1
lst.append(price)
arg = sum(lst) / len(lst)
print(arg)
return func
?
f = buy_car()
print(f.__closure__)
print(f.__code__.co_freevars) # 查看自由变量
print(f.__code__.co_varnames) # 查看局部变量
f(1)
f(2)
f(3)
f(4)
f(5)
22.装饰器
-
装饰器就是在原有基础的功能上添加新的功能的工具
-
开放封闭原则
-
对扩展开放,支持增加新功能
-
对修改的源代码是封闭的,对调用方式是封闭的
-
-
time
import time ###标准库
def index():
time.sleep(2)
print("我真帅")
index()
?
#标准版装饰器
def wrapper(f):
def inner(*args,**kwargs):
#被执行函数之前
ret = f(*args,**kwargs)
#被执行函数之后
return ret
return inner
@wrapper() ###func=wrapper(func)
def func()
print("我是被装饰函数")
#实例
####被装饰函数未传参
def wrapper(f):
def inner(*args,**kwargs):
print("我是爹,我先走")
ret = f() #
print("你是儿子,你后走")
return ret
return inner
@wrapper
def func():
return "我是女娲"
print(func())
>>>
我是爹,我先走
你是儿子,你后走
我是女娲
####被装饰函数传参
def wrapper(f):
def inner(*args,**kwargs):
print("我是爹,我先走")
ret = f(*args,**kwargs)
print("你是儿子,你后走")
return ret
return inner
@wrapper
def func(a,b,c):
print(f"我是女娲{a},{b},{c}")
func("ss","ww","yy")
#语法糖
-
语法糖必须要放在被装饰的函数正上方
-
语法糖的本质:被装饰的函数=装饰器函数(被装饰的函数)
import time
def run_time(f): #f接收的是被装饰的函数名 #run_time就是一个闭包
def inner(*args,**kwargs): #被装饰的函数需要的参数
strat_time = time.time() #被装饰函数之前
print("外挂开启")
ret = f(*args,**kwargs)
print("外挂结束")
print(time.time() - strat_time) #被装饰函数之后
return ret
return inner
@run_time #语法糖的本质---> index=run_time(index)
def index(user,pwd,hero):
print("登录游戏")
print(f"账号{user}密码{pwd}英雄{hero}")
print("游戏中")
return "游戏结束"
print(index(‘meet‘,‘1234‘,‘草丛伦‘))
>>>
#有参装饰器
-
应用场景:flask框架的路由就是有参装饰器
##未带参数的装饰器
def wrapper(f):
def inner(*args,**kwargs):
#被执行函数之前
ret = f(*args,**kwargs)
#被执行函数之后
return ret
return inner
@wrapper() ###func=wrapper(func)
def func()
print("我是被装饰函数")
##带参数的装饰器
def wark(arg):
def wrapper(func):
def inner(*args,**kwargs):
ret = func1()
return ret
return inner
return wrapper
@wark(chose)
def func1():
print("我是被装饰函数")
##wrapper = wark(chose)
##func1 = wrapper(func1)
##func1()
#多个装饰器装饰一个函数
-
多个装饰器装饰一个函数时先执行离被装饰的函数最近的装饰器
-
实例
def f1(func): # func == index
def f2(*args,**kwargs):
print("这是f1的装饰开始")
func(*args,**kwargs)
print("这是f1的装饰结束")
return f2
def foo1(func): # func == f2
def foo2(*args,**kwargs):
print("这是foo1的装饰开始")
func(*args,**kwargs)
print("这是foo1的装饰结束")
return foo2
@foo1 # index = foo1(index) # index = foo1(f2)
@f1 # index = f1(index) # 现在的index其实就是返回的f2
def index():
print("is index")
index() # foo2()
def f1(func): # func == index
def f2(*args,**kwargs):
print("sss")
func(*args,**kwargs)
print("stop")
return f2
def foo1(func): # func == f2
def foo2(*args,**kwargs):
print("good")
func(*args,**kwargs)
print("bbb")
return foo2
def ff(func):
def ff2():
print("is ff")
func()
print("ff is")
return ff2
@foo1
@ff
@f1
def f():
print("is f")
f()
>>>
good
is ff
sss
is f
stop
ff is
bbb
23.递归
-
定义:
-
不断地调用自己本身,##只满足这个条件的就是死递归
-
有明确的结束条件
-
-
递归最大深度:官方1000 实测994
-
阶乘5层
def jc(n):
if n == 5:
return 5
return jc(n+1) * n
print(jc(1))
>>>> 120
-
斐波那契数列
lst = [1,1]
for i in range(5):
lst.append(lst[-1] + lst[-2])
print(lst)
函数:
还没做出来
24.函数:
def 函数名():
函数体
-
封装代码,减少重复的代码。
-
函数被调用后,函数体中开辟的空间会被自动销毁
-
函数名+括号(),有两个功能:第一个是调用函数,第二个是接受返回值
-
不管在什么位置,只要看到函数名+()就是调用函数
#return
-
在函数中遇到return直接结束函数
-
可以给函数的执行者返回任意数据类型
-
可以给函数的执行者返回多个数据类型(以元组形式接受)
-
函数体中不写return,默认返回None。写了return不写值,也是返回None
def func():
print(1)
func() >>>1 ##不打印函数,只执行函数,只会执行函数体
def func():
print(1) ##函数体中不写return,默认返回None
print(func())
>>>>1
None ##只有在print打印函数时,才会打印出None
#函数传参优先级
-
函数传参优先级:位置参数>*args(动态位置参数)>默认值参数>**kwargs(动态关键字参数)
#参数
-
形参 : 写在函数声明的位置的变量叫形参(在定义函数的阶段)
-
可以单独使用位置参数,也可单独使用默认参数,也可混合使用
-
位置参数:必须要一一对应
def yue(app,girl,age,addr): # 形参
print(f"打开{app}")
print(f"找一位{girl},要求年龄:{age},地区:{addr}的人")
yue("微信","女孩",18,"乌克兰") # 实参 按照位置传参
-
默认参数:可以不传,可以传,传的时候会将默认值覆盖
def userinfo(name,age,hobby,sex="男"): #sex就有默认值
print(f"姓名:{name} 年龄:{age} 性别:{sex} 爱好:{hobby}")
userinfo("岳新力",23,"开车")
-
动态位置参数(*args)
-
在函数定义阶段,*就是聚合
-
在函数体中,*就是打散list或tuple,**就是打散dict
-
*args 程序员之间的约定俗称(可以更换,但不建议更换)
-
能够接受不固定长度的参数
-
位置参数过多时可以使用动态参数
-
获取到的是一个元组,没有值就是一个空元组
-
只接受多余的位置参数
def lst(a,b,c,*args,d=100,): #*args 此处的*是聚合
print(a,c,w,d)
print( *args) #*args 此处的*是打散
print(args)
lst(1,2,3,4,5,6,7)
>>>>1 3 (4, 5, 6, 7) 100
>>>>4 5 6 7
(4 5 6 7)
?
#######################################################################
?
def foo(a, b, args, c, sex=None, **kwargs):
print(a,b,c)
print(args) #此处的args前没有* 所有没有将列表打散
print(kwargs) #此处的kwargs前没有* 所有没有将字典打散
?
?
-
-
动态关键字参数(**kwargs)
-
在函数定义阶段,*就是聚合
-
在函数体中,**kwargs就是打散字典,获取到的是键
-
-
程序员之间的约定俗称(可以更好,但是不建议更换)
-
获取到的是一个字典,没有值时就是一个空字典
-
只接受多余的关键字参数
def func(**kwargs): # 万能传参
print(kwargs)
func(c=22,a=1,b=2)
>>>>{‘c‘: 22, ‘a‘: 1, ‘b‘: 2}
-
-
万能传参(面试必问)
def func(*args,**kwargs): # 万能传参
print(args,kwargs)
func(12,2,121,12,321,3,a=1,b=2)
>>>>(12, 2, 121, 12, 321, 3) {‘a‘: 1, ‘b‘: 2}
###############################################################################
def foo(a, b, *args, c, sex=None, **kwargs):
print(a,b,c)
print(args)
print(kwargs)
print(*args)
print(*kwargs)
foo(*[1, 2, 3, 4],**{‘name‘:‘太白‘,‘c‘:12,‘sex‘:‘女‘}) #*[]打散列表 **{}打散字典
>>>
1 2 12
(3, 4)
{‘name‘: ‘太白‘}
3 4
name
-
-
实参:在函数调用的时候给函数传递的值(调用函数的阶段)
-
可以单独使用位置参数,也可单独使用关键字参数,也可混合使用
-
位置参数:必须要一一对应
-
关键字参数:指名道姓传参
-
混合参数:位置参数 > 默认参数
def yue(chat): # chat 形参
?
print("拿出手机")
?
print("打开"+chat)
?
yue("陌陌") # "陌陌"在这里就是实参
-
#注释
-
查看函数的注释
def add(a:int,b:int): # 提示(a:int)只是提示用户需要传参的类型,不是字典赋值
""" ####此处的注释必须都是三个双引号(三个单引号也可以)
加法
:param a:
:param b:
:return:
"""
return a + b
print(add(1,2)) >>>>3
print(add("1","2")) >>>>12
print(add.__doc__)
>>>>
加法
:param a:
:param b:
:return:
#函数的名称空间
-
名称空间
-
内置空间 #存放python自带的一些函数
-
全局空间 #当前python文件定格编写的代码开辟的空间
-
局部空间 #函数开辟的空间
-
-
程序的加载顺序
内置空间 > 全局空间 > 局部空间
-
程序的取值顺序
局部空间 > 全局空间 > 内置空间
#作用域
-
全局作用域: 包含内置命名空间和全局命名空间. 在整个文件的任何位置都可以使用(遵循 从上到下逐?执行).
-
globals() 查看全局作用域:内置+全局
-
-
局部作用域: 在函数内部可以使用.
-
locals() 查看当前作用域:建议查看局部作用域
-
def func():
a = 40
b = 20
print("哈哈")
print(a, b)
print(globals()) # 打印全局作用域中的内容
print(locals()) # 打印当前作用域中的内容
func()
>>>>
哈哈
40 20
{‘__name__‘: ‘__main__‘, ‘__doc__‘: None, ‘__package__‘: None, ‘__loader__‘: <_frozen_importlib_external.SourceFileLoader object at 0x000001D4A2DDF848>, ‘__spec__‘: None, ‘__annotations__‘: {}, ‘__builtins__‘: <module ‘builtins‘ (built-in)>, ‘__file__‘: ‘F:/学习/python-lch/python26期视频/day10/代码和笔记/06 函数的名称空间.py‘, ‘__cached__‘: None, ‘a‘: 10, ‘func‘: <function func at 0x000001D4A2E97288>}
{‘a‘: 40, ‘b‘: 20}
#函数名的第一类对象及使用
-
函数名可以当做值,赋值给一个变量
def func():
print(1)
a = func
print(func) >>>> # 打印函数的内存地址
print(a) #打印函数的内存地址
a() #执行func函数
>>>><function func at 0x0000021BB93B7318>
>>>><function func at 0x0000021BB93B7318>
>>>>1
-
函数名可以当做另一个函数的参数来使用
def func():
print(1)
def foo(a): # a = func
print(a) # func这个函数的内存地址
foo(func) #此处函数foo的参数是func不是func()
>>>><function func at 0x0000026EC54673A8>
def func(): ###被执行,打印一个1
print(1)
def foo(a): ##a = func(), return None
print(a) ##将None打印出来
foo(func()) #此处函数foo的参数是func不是func()
>>>>1 None
-
函数名可以当做另一个函数的返回值
-
函数名可以当做元素存储在容器中
def login():
print("登录")
?
def register():
print("注册")
msg ="""
1.注册
2.登录
请输入您要选择的序号:
"""
func_dic = {"1":register,"2":login}
while True:
choose = input(msg) # "5"
if choose in func_dic:
func_dic[choose]()
else:
print("滚")
#函数的嵌套
-
交叉嵌套
def func():
foo()
def foo():
print(111)
func()
-
嵌套
def func(a,b): #a = 4 b = 7
def foo(b,a): #b = 4 a = 7
print(b,a) #4 7
return foo(a,b) #先执行函数调用 a = 4 b= 7
# return None
a = func(4,7)
print(a)
>>>4 7
>>>None
-
global
-
只修改全局空间中的变量
-
在局部空间中可以使用全局中的变量,但是不能修改,如果要是要强制修改需要添加global
-
当变量在全局中存在时,global就是申明我要修改全局的变量,并且会在全局修改这个变量
-
当变量在全局中不存在时,global就是申明要在全局中创建一个变量,并且会在全局修改这个变量
-
-
nolocal
-
只修改局部空间中的变量,最外层的一个函数
-
只修改离nonlocal最近的的一层,如果这一层没有就继续往上一层进行查找,只能在局部
-
nonlocal不能创建变量
-
25.匿名函数
-
匿名函数的名字叫做lambda
-
匿名函数的编写格式
f = lambda a,b:a+b
print(f(1,2)) >>>3
####################
def num():
return [lambda x:i * x for i in [1,2]]
a= num()
print(a) >>>获取到三个内存地址
?
print((lambda a,b:a+b)(1,2))
#lambda和def是一样的
#a,b和(a,b)是一样的 代表形参
#: a+b 和 return a+b 是一样的 代表返回值
# 形参: 可以接受位置参数,动态位置,默认,动态关键,可以不写
# :返回值 只能返回一个数据,必须写
?
f = lambda x,y:(x,y,x+y)
print(f.__name__) >>><lambda>
print(f(1,2)) >>>(1,2,3)
-
例子
-
算数
def square(x) : # 计算平方数
return x ** 2
map(square, [1,2,3,4,5]) # 计算列表各个元素的平方
[1, 4, 9, 16, 25]
>>> map(lambda x: x ** 2, [1, 2, 3, 4, 5]) # 使用 lambda 匿名函数
[1, 4, 9, 16, 25]
-
-
字典
func = lambda a,b,*args,sex= ‘alex‘,c,**kwargs: kwargs
print(func(3, 4,c=666,name=‘alex‘)) >>>{‘name‘: ‘alex‘}
-
索引
func = lambda x:(x[0],x[3])
print(func(‘afafasd‘)) >>>(‘a‘, ‘f‘)
-
比较大小
func = lambda x,y: x if x > y else y
print(func(3,100)) >>>100
-
###匿名函数题##
def num():
return [lambda x:i*x for i in range(3)] # [func,func,func]
print([m(3) for m in num()])
?
def num():
lst = []
for i in range(3)
def func(x):
return i*x
lst.append(func)
return lst
new_list = []
for m in num():
new_list.append(m(3))
print(new_list)
26.软件开发规范
-
各个文件夹
-
bin ----启动文件
-
lib ----公共组件
-
core ----主逻辑
-
db ----存储数据
-
log ---记录日志
-
conf ---配置文件
-
27.log日志
-
记录程序的运行状态
-
记录用户的操作
#日志的级别
-
debug调试 --10
-
info 信息 --20
-
warning警告 --30
-
error 错误 --40
-
srirical 危险 --50
#日志文件写入
import logging
logger = logging.getLogger()
#创建一个空架子
fh = logging.FileHandler("test.log",mode = "a",encoding = "utf-8")
#创建一个文件句柄,用来记录日志
ch = logging.StreamHandler()
#创建一个屏幕流,打印记录的内容
f_str = logging.Formatter("%(asctime)s %(name)s %(levelname)s %(filename)s %(lineno)s %(message)s")
##d定义一个记录日志的格式
logger.level = 10 #设置一个记录级别
fh.setFormatter(f_str) #给文件句柄设置记录的格式
ch.setFormatter(f_str) #给中控台设置打印内容的格式
logger.addHandler(fh) #将文件句柄添加logger对象中
logger.addHandler(ch) #将中控台添加的logger对象中
logger.debug(1234)
logger.info(1234)
logger.warning(1234)
logger.error(1234)
logger.critical(1234)
28.包
-
具有—init—.py文件的文件夹就是一个包,目的就是管理模块
-
包的本质就是一个模块,模块可以导入,包也可以导入
Python2中,使用import一个包时,包中没有--init--.py报错
Python3中,使用import一个包时,包中没有--init--.py不报错
-
导入时,发现使用.(点)的操作就是导入包
-
导入前.(点)前面必须是一包
#路径
-
绝对路径:从最没外层的开始查找
-
相对路径:取决于在哪个文件中启动
#import 包.包.模块
-
import bake.api.versions
##bake是包 api也是包 version是模块
#起别名
-
import bake1.api.versions as v
#from 包.包.模块 import 函数,变量,*
29垃圾回收机制
-
概述:python采用的是引用计数机制为主,标记-清除和分代收集两种机制为辅的策略
-
引用计数:
-
每当新的引用指向该对象时,引用计数加1,当对该对象的引用失效时,引用计数减1,当对象的引用计数为0时,对象被回收。缺点是,需要额外的空间来维护引用计数,并且无法解决对象的循环引用。
-
-
分代回收:
-
-
以时间换空间的回收方式
-
分代回收是一种以空间换时间的操作方式,Python将内存根据对象的存活时间划分为不同的集合,每个集合称为一个代,Python将内存分为了3“代”,分别为年轻代(第0代)、中年代(第1代)、老年代(第2代),他们对应的是3个链表,它们的垃圾收集频率与对象的存活时间的增大而减小。
-
新创建的对象都会分配在年轻代,年轻代链表的总数达到上限时,Python垃圾收集机制就会被触发,把那些可以被回收的对象回收掉,而那些不会回收的对象就会被移到中年代去,依此类推,老年代中的对象是存活时间最久的对象,甚至是存活于整个系统的生命周期内。
-
同时,分代回收是建立在标记清除技术基础之上。分代回收同样作为Python的辅助垃圾收集技术处理那些容器对象
-
-
标记清除:
-
活动对象会被打上标记,会把那些没有被打上标记的非活动对象进行回收。
-
30什么是断言
-
assert是用来检查一个条件,如果它为真,就不做任何事。如果它为假,则会抛出AssertError并且包含错误信息。
-
应用场景:
-
防御型编程
-
运行时检查程序逻辑
-
-
程序常量
-
-
以上是关于Python基础学习的主要内容,如果未能解决你的问题,请参考以下文章