前言 语言:Python(python==3.9)
编译软件:VScode、PyCharm
环境:Anaconda
一、Python注释和输入输出 注释分为单行注释,多行注释,被注释的代码不会运行,快捷键:选中代码+Ctrl+/
主要功能有:
1.对代码进行注释,方便进行理解
2.对代码进行禁用
1.单行注释
**运行结果:**123
2.多行注释 1 2 3 4 5 6 """ 三引号 引号内代码都注释 随便写多少行 """ print ("hello" )
**运行结果:**hello
3.输入和输出 1 2 3 4 5 6 7 print ("打印文本" )print ("打印数字:" ,123 )print ("文本1" ,"文本2" ,"文本3" ,sep = "-" )print ("文本1" ,end = "\n" )print ("文本2" ,end = "123" )print ("文本3" ,end = "\n" )
运行结果:
打印文本 打印数字: 123 文本1-文本2-文本3 文本1 文本2123文本3
1 2 3 4 5 print (123 )x = input ("打印到控制台,让程序暂停,等待用户输入" ) print (x)print (456 )
运行结果:
123 444(将在控制台显示“打印到控制台,让程序暂停,等待用户输入”,等到用户输入后再运行下面的程序,这里输入444,输出444) 456
二、变量 什么是变量:用一个简短的名称来代替数据的使用
1.数值 1 2 3 a = 100 print (a)print (100 )
2.字符串
3.变量名称的要求 一般场景下必须使用变量来保存数据,如果不需要使用到的数据需要接收,则用下划线“_”表示变量名
1 2 3 4 x = 123 y = "nihao" _ = 200 print (x,y,_)
变量名字必须是连续的字母,下划线,数字的组合。错误的命名方法:first name = “123”
数字不可以作为变量名的开头,变量名严格区分大小写Name和name是两个不同的变量
1 2 1app_version = "1.1.0" print (1app_version)
官方提供的关键字不可以作为变量名
中文作为变量名?可以,只要是Unicode编码符合的字符都可以作为变量名,一般约定用英文或者拼音字母而不用汉字
1 2 华清远见 = "华清远见成都分中心在西南交大地铁站旁" print (华清远见)
常把大写字母的变量名作为不改变的常量使用
4.变量名命名规则 三种写法:
1.小驼峰:huaQingYuanJian
2.大驼峰:AppVersion
3.匈牙利命名法(比较常用):ai_first_class_1
三、变量的赋值与取值 1.数据直接量 1 2 3 4 x = 100 x_2 = "hello" print (x)
2.表达式
3.多变量一起赋值 1 2 a = b = c = 100 print (a,b,c)
4.解构赋值 1 2 w,m,n = 100 ,10 ,1 print (w,m,n)
5.变量的取值 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 x = 10 x = 1 print (x)x1 = 10 x2 = 20 x3 = 30 c = 666 ,x1,x2,x3 print (c)x1,a,b,c= 666 ,x1,x2,x3 print (x1,a,b,c)x1 = 10 x2 = 20 x1,x2 = x2,x1 print (x1,x2)
四、字符串 1.字符串的写法 1 2 3 4 x_1 = "我是一个字符串" x_2 = "" x_3 = " " print (type (x_2))
1 2 3 4 5 6 7 x1 = "hello" x2 = "hi" x3 = """三引号也可以是字符串 可以随意换行 自带换行符 """ print (x3)
运行结果:
三引号也可以是字符串 可以随意换行 自带换行符
2.转义字符 1 2 3 4 5 6 7 8 9 10 11 12 13 14 x1 = "我爱我的祖国和我的家乡\"四川\"" print (x1)x2 = '我爱我的祖国和我的家乡\'四川\'' print (x2)x3 = "我爱我的祖国和我的家乡'四川'" print (x3)x4 = "你好:\n 欢迎你" print (x4)x5 = "abcd\\efg\\hi" print (x5)x6 = "abc\tdef\tghi" print (x6)x7 = r"D:\桌面\华清\3.8\code\06-字符串.ipynb" print (x7)
运行结果:
我爱我的祖国和我的家乡”四川” 我爱我的祖国和我的家乡’四川’ 我爱我的祖国和我的家乡’四川’ 你好: 欢迎你 abcd\efg\hi abc def ghi D:\桌面\华清\3.8\code\06-字符串.ipynb
3.字符串常用运算操作 加号:
1 2 3 4 x1 = "华清远见" x2 = "成都分中心" str_1 = x1 + x2 print (str )
1 2 3 4 5 6 7 x3 = "我的年龄是:" x4 = "18" str_2 = x3 + x4 print (str_2)x5 = '华清' '远见' '666' print (x5)
乘号:
1 2 3 4 x6 = "abc" str_3 = x6*3 print (str_3)
运行结果:
华清远见成都分中心 我的年龄是:18 华清远见666 abcabcabc
等号:(严格区分大小写)
1 2 3 x1 = "abc" x2 = "Abc" print (x1==x2)
运行结果:
False
4.访问子串 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 x7 = "华清远见成都分中心" xx_7 = x7[0 ] print (xx_7)xx_77 = x7[-1 ] print (xx_77)xx__77 = x7[2 :10 :2 ] print (xx__77)xx__78 = x7[::2 ] print (xx__78)xx__79 = x7[:6 :2 ] print (xx__79)xx__70 = x7[-1 :6 :2 ] print (xx__70)xx__74 = x7[9 :3 :-1 ] print (xx__74)
运行结果:
华 心 远成分心 华远成分心 华远成
心中分都成
比较常用的三个:
1 2 3 4 5 6 7 8 xx__71 = x7[::-1 ] print (xx__71)xx__72 = x7[:-1 ] print (xx__72)xx__73 = x7[-1 ] print (xx__73)
运行结果:
心中分都成见远清华 华清远见成都分中 心
5.输入一个字符串,判断是否回文 1 2 3 x1 = input ("请输入字符串" ) x2 = x1[::-1 ] print (x1==x2)
**运行结果:**True
6.判断一个字符串是否为另一个字符串的子串 1 2 3 4 5 6 x1 = "abcdefg" x2 = "ab" x3 = "gh" print (x1 in x2)print (x3 in x1)print (x3 not in x1)
运行结果:
False False True
7.查看字符串字符数量(长度) 1 2 3 x1 = "abc" n = len (x1) print (n)
**运行结果:**3
8.常见占位符 1 2 3 4 5 6 7 8 9 10 11 12 13 占位符和类型码 | 占位符和类型码 | 说明 | | :------------: | ------------------------------------------------------------ | | %s | 转成字符串, 使用 str (x) 函数转换(常用) | | %d | 转成十进制的整数(常用) | | %o | 转成八进制的整数 | | %x,%X | 转成十六进制的整数 | | %e,%E | 转成指数格式的浮点数 | | %f,%F | 转成小数格式的浮点数(常用) | | %g,%G | 转成指数格式或小数格式的浮点数 | | %% | 转成一个% | | %m.nf | m是指总宽度,默认右对齐,加个 - 表示左对齐,n 是指保留的小数点位数 |
9.字符串格式化表达式 常用来在训练自己的神经网络模型时,控制台查看数据情况
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 x1 = "我叫%s今年%d岁" %("jack" ,23 ) print (x1)x2 = "精确度是%.2f" %(100 ) print (x2)x3 = "精确度是%50.3f" %(100 ) print (x3)x4 = "十六进制的值是%x" %(11 ) print (x4)x5 = "科学计数法表示为%g" %(1000000000 ) print (x5)
运行结果:
我叫jack今年23岁 精确度是100.00 精确度是 100.000 十六进制的值是b 科学计数法表示为1e+09
10.另外一种格式化字符串的方式 1 2 3 4 5 6 7 r = 144 g = 127 b = 255 x1 = "rgb(144,127,255)" x2 = f"rgb({r} ,{g} ,{b} )" print (x1)print (x2)
运行结果:
rgb(144,127,255) rgb(144,127,255)
11.字符串常用的一些API(别人写的一些函数,可以直接调用) 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 text = "HELLO world" text2 = text.lower() print (text2)text3 = text.upper() print (text3)text4 = text.capitalize() print (text4)text = " 1825648 " text5 = text.strip() print (text5)text = "hello my name is jack" text6 = text.split() print (text6)text = "http://www.hqyj.com/index.html?user_id=123&user_name=jack&count=20" text7 = text.split("?" )[0 ] print (text7)text8 = text.split("?" )[1 ].split("&" )[1 ].split("=" )[1 ] print (text8)text = ['hello' , 'my' , 'name' , 'is' , 'jack' ] text9 = "-" .join(text) print (text9)text = "你好,我叫李华" text0 = text.replace("李华" ,"李雷" ) print (text0)text = "hello,my name is lihua" text11 = text.find("lihua" ,19 ) print (text11)text = "std = 1" text12 = text.startswith("std" ) print (text12)text = "std = 1,name" text13 = text.endswith("name" ) print (text13)text = "1600" text14 = text.isdigit() print (text14)text = "1600yuan" text15 = text.isalpha() print (text15)text = " price = 1600_yuan" text16 = text.isalnum() print (text16)text17 = text.title() print (text17)text18 = text.capitalize() print (text18)text = "Hello, World! Hello, Python!" text19 = text.count("Hello" ) print (text19)name = "jack" age = 18 text20 = f"my name is {name} , i am {age} year old" print (text20)
运行结果:
hello world HELLO WORLD Hello world 1825648 [‘hello’, ‘my’, ‘name’, ‘is’, ‘jack’] http://www.hqyj.com/index.html jack hello-my-name-is-jack 你好,我叫李雷 -1 True False True False False Price = 1600_Yuan price = 1600_yuan 2 my name is jack, i am 18 year old False
五、数值型 1.进制 十进制
八进制,打印默认转化为十进制数
十六进制
二进制
运行结果:
64 859133 81
2.浮点数与科学计数法 1 2 3 4 5 6 7 8 9 10 11 x = 1.0 y = 2. z = .6 x = 1e6 y = 2e03 z = 3e-3 import mathPI = math.pi PI
3.数字类型转换 1 2 3 4 5 6 7 8 9 x = 6 x1 = bin (x) x2 = oct (x) x3 = hex (x) x4 = float (x) x5 = complex (x) x = 3.0 x6 = int (x) print (x1,x2,x3,x4,x5,x6)
math.ceil(x)函数返回大于或等于x的最小整数。 math.floor(x)函数返回小于或等于x的最大整数。
1 2 print (math.ceil(3.14 ))print (math.floor(3.94 ))
运行结果:
0b110 0o6 0x6 6.0 (6+0j) 3 4 3
4.布尔类型 1 2 3 4 5 6 7 8 x = 0 print (bool (x))y = "" print (bool (y))z = "0" print (bool (z))print (10 <20 )
运行结果:
False False True True
5.字节串和空值 1 2 3 4 5 6 7 text = b"hello" print (type (text))x = None print (x)
六、列表 1.字面量 1 2 3 4 5 6 x = [] print (type (x))x = [1 , 2 , 3 , 4 , 5 ] print (x)x = [1 , 2 , [3 ,4 ]] print (x)
2.通过构造函数来创建列表
3.list函数可以传入一个可迭代对象用于创建列表中数据 1 2 3 4 5 x = list ("hello" ) print (x)x = list (range (10 )) print (x)
4.列表的运算 1 2 3 4 5 6 7 y = [4 ,5 ,6 ] num = 5 z = x + y print (z)print (z)z = x * num
5.in / not in 1 2 3 x = ["a" ,"b" ,"c" ] print ("a" in x)print ("b" not in x)
6.列表切片 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 lst = [1 ,5 ,6 ,9 ,8 ,10 ] Lst_1 = lst[2 ] lst_2 = lst[2 :5 :2 ] lst_3 = lst[::-1 ] print (Lst_1,lst_2,lst_3)
运行结果:
6 [6, 8] [10, 8, 9, 6, 5, 1]
7.列表的操作 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 x = [10 , 20 , 30 ] re = x.append(40 ) print (x,re)x.insert(2 ,666 ) print (x)x.extend([9 ,99 ,999 ]) print (x)x_1 = [1 ,2 ,3 ] print (id (x_1))x_2 = [1 ,2 ,3 ] x_3 = x_1 + x_2 x_1.extend(x_2) print (id (x_1))print (id (x_2))print (id (x_3))x = [1 ,2 ,3 ,5 ,6 ,8 ,9 ,7 ,1 ,2 ] x[2 ] = 666 print (x)print (x[2 :100 ])x.remove(666 ) print (x)x.pop(1 ) print (x)x.clear() print (x)x = [1 ,2 ,3 ,5 ,6 ,8 ,9 ,7 ,1 ,2 ] del xx = [1 ,2 ,3 ,5 ,6 ,8 ,9 ,7 ,1 ,2 ] print (x.index(1 ))print (x.index(max (x)))
运行结果:
[10, 20, 30, 40] None [10, 20, 666, 30, 40] [10, 20, 666, 30, 40, 9, 99, 999] 2303722066048 2303722066048 2303722068160 2303722005568 [1, 2, 666, 5, 6, 8, 9, 7, 1, 2] [666, 5, 6, 8, 9, 7, 1, 2] [1, 2, 5, 6, 8, 9, 7, 1, 2] [1, 5, 6, 8, 9, 7, 1, 2] []
0 6
七、元组 元组和列表一样是保存数据的容器
1.创建元组 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 x = () x = (1 ,2 ,3 ,5 ,6 ,8 ,5 ,4 ,2 ,5 ) print (x)print (x[1 ])print (x[2 :5 ])x = (10 ) y = (10 ,) print (type (x))print (type (y))x = 10 ,"hello" ,True print (type (x))x = tuple (range (5 )) print (x)
运行结果:
(1, 2, 3, 5, 6, 8, 5, 4, 2, 5) 2 (3, 5, 6) <class ‘int’> <class ‘tuple’> <class ‘tuple’> (0, 1, 2, 3, 4)
2.元组的操作 1 2 3 4 x = (1 ,"name" ,"jack" ,6 ,5 ) print ((x[1 ]))
3.解构赋值 解构赋值必须左右的结构一致
1 2 x1,x2 = (10 ,20 ) print (x1,x2)
4.元组的运算 1 2 3 4 x = (10 ,20 ) y = (30 ,40 ) print (x+y)print (x * 3 )
5.将其他数据类型转换为元组 1 2 3 4 5 6 x_1 = [1 ,2 ,5 ,6 ] x_2 = "nihao" ,"yes" ,"no" print (tuple (x_1),tuple (x_2))count = x_2.count("no" ) print (count)
八、字典 1.创建空字典 字典的元素没有下标,只有键和值
1 2 3 4 5 6 7 8 9 10 11 12 13 14 d = {} print (d)d = dict ([("name" ,"xiaowang" ),("age" ,18 )]) print (d)d = dict (a = 1 , b = 2 , c = 3 ) print (d)title = {"name" :"jack" ,"age" :"18" ,"age" :"10" } print (title["age" ])title = {"name" :"jack" ,"age" :"18" ,"home" :"beijing" } print (title)d = {(1 ,2 ,3 ):"id_num" ,"age" :18 } print (d)
运行结果:
{} {‘name’: ‘xiaowang’, ‘age’: 18} {‘a’: 1, ‘b’: 2, ‘c’: 3} 10 {‘name’: ‘jack’, ‘age’: ‘18’, ‘home’: ‘beijing’} {(1, 2, 3): ‘id_num’, ‘age’: 18}
2.字典的操作 1 2 3 4 5 6 7 title = {"name" :"jack" ,"age" :18 ,"home" :"beijing" } title["age" ] = 20 print (title)title["school" ]="swust" print (title)print (title["home" ])
运行结果:
{‘name’: ‘jack’, ‘age’: 20, ‘home’: ‘beijing’} {‘name’: ‘jack’, ‘age’: 20, ‘home’: ‘beijing’, ‘school’: ‘swust’} beijing
3.in/not in 只能用来判断键
1 2 3 title = {"name" :"jack" ,"age" :18 ,"home" :"beijing" } print ("name" in title)print ("jack" in title)
运行结果:
True False
4.删除字典 1 2 3 4 5 6 title = {"name" :"jack" ,"age" :18 ,"home" :"beijing" } del title["name" ]print (title)title.clear() print (title)del title
运行结果:
{‘age’: 18, ‘home’: ‘beijing’} {}
5.常见API 1 2 3 title = {"name" :"jack" ,"age" :18 ,"home" :"beijing" } print (len (title))print (type (title))
运行结果: 3 <class ‘dict’>
把字典的字面量变成字符串,网络传输的时候,常常会把这种格式的字符串进行传输(JSON)
1 2 str1 = str (title) print (str1,type (str1))
运行结果: {‘name’: ‘jack’, ‘age’: 18, ‘home’: ‘beijing’} <class ‘str’>
6.字典的一些方法 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 title = {"name" :"jack" ,"age" :18 ,"home" :"beijing" } title.clear() print (title)title = {"name" :"jack" ,"age" :18 ,"home" :"beijing" } str1 = title.copy() print (str1)print (id (title),id (str1))str1["name" ] = "mary" print (str1,title)str2 = title.get("age" ) print (str2)str2 = title["age" ] print (str2)str2 = title.get("nn" ,"None" ) print (str2)items = title.items() print (type (items))for key,value in items: print (key,value) keys = title.keys() for key in keys: print (key) values = title.values() for value in values: print (value) title_1 = {"name" :"jack" ,"age" :18 ,"home" :"beijing" } title_2 = {"food" :"vegetable" } title_1.update(title_2) print (title_1)title.pop("name" ) title["age" ] = None print (title)
运行结果:
{} {‘name’: ‘jack’, ‘age’: 18, ‘home’: ‘beijing’} 2594022048448 2594031191872 {‘name’: ‘mary’, ‘age’: 18, ‘home’: ‘beijing’} {‘name’: ‘jack’, ‘age’: 18, ‘home’: ‘beijing’} 18 18 None <class ‘dict_items’> name jack age 18 home beijing name age home jack 18 beijing {‘name’: ‘jack’, ‘age’: 18, ‘home’: ‘beijing’, ‘food’: ‘vegetable’} {‘age’: None, ‘home’: ‘beijing’}
九、集合 1.创建集合 1 2 3 4 5 6 7 8 9 10 11 12 s1 = set () print (s1)s2 = set ([1 ,2 ,3 ,8 ,5 ]) print (s2)s2 = set (range (5 )) print (s2)s3 = {10 ,20 ,30 } print (s3)
集合中不存在相同元素并且元素需要是不可变类型
1 2 s4 = {10 ,20 ,(2 ,3 ),10 ,1 } print (s4)
易混点
1 2 3 4 5 6 7 s5 = {(10 )} print (s5)s6 = {(10 ,),(10 ,),} print (s6)
运行结果:
{10}
{(10,)}
只有在python中相等,比较的是元素的值而不是地址
1 2 3 4 x = (10 ,20 ) y = (10 ,20 ) print (x==y)print (id (x)==id (y))
2.案例 假设有一万个数字,每一个数字代表张图片的类别,用集合来查看到底有多少种类别
1 2 3 x = [0 ,0 ,0 ,0 ,1 ,1 ,1 ,1 ,2 ,2 ,4 ,4 ,4 ,4 ,4 ,4 ,2 ,2 ,1 ,1 ,1 ,1 ,0 ,0 ,0 ,0 ,3 ,3 ,3 ,3 ,3 ,5 ,1 ,2 ,2 ,1 ] print (set (x))
3.固定集合 不可以更改元素
1 2 3 s1 = frozenset ([1 ,2 ,3 ,4 ,5 ,5 ,6 ]) print (s1)
4.eval()函数 常出现在企业级别的项目中,向项目中添加代码
1 2 3 4 5 6 7 8 9 str1 = "10+20" eval (str1)lst = [1 , 5 , 6 , 4 , 5 , 2 , 3 ] str2 = "+" .join(map (str , lst)) print (eval (str2))
十、运算符 1.逻辑运算符 A and B
A是一个表达式,B也是一个表达式
如果bool(A)为False,那么B不运行,否则整个表达式的结果为B的结果
1 2 3 4 5 6 7 8 x1 = 100 x2 = 200 x3 = 0 x = x1 and x2 print (x)x = x3 and x2 print (x)
运行结果:
200 0
A or B
如果bool(A)为True,那么B不运行,否则整个表达式的结果为B的结果
1 2 3 4 x = x1 or x2 print (x)x = x3 or x2 print (x)
运行结果:
100 200
not A
如果bool(A)为True,那么not A的结果为False,否则not A的结果为True
1 2 3 4 x = not x1 print (x)x = not x3 print (x)
运行结果:
False True
2.位运算符 1 2 3 4 5 6 7 8 9 10 11 12 13 x1 = 0b1010 x2 = 0b1100 print (x1 & x2)print (x1 | x2)print (x1 ^ x2)print (~x1)
运行结果:
8
14
6
-11
1 2 3 4 5 6 7 x1 = x1^x2 x2 = x1^x2 x1 = x1^x2 print (x1,x2)
运行结果:
12 10
左移运算符
左移运算符是将一个数字的二进制位全部左移若干位,高位丢弃,低位补0。
1 2 3 4 5 x1 = 0b1010 x2 = 2 print (x1 << x2)
右移运算符是将一个数字的二进制位全部右移若干位,低位丢弃,高位补0。
右移运算符
1 2 3 4 5 x1 = 0b1010 x2 = 2 print (x1 >> x2)
运行结果:
40
2
3.身份运算符 1 2 3 4 a = 10 b = 10 print (a is b) print (a is not b)
4.成员运算符 1 2 3 4 a = [1 , 2 , 3 , 4 , 5 ] b = 3 print (b in a) print (b not in a)
5.三元运算符 1 2 3 4 a = 10 b = 20 result = a if a > b else b print (result)
运行结果:
20
十一、表达式 \1. 算术表达式
\2. 逻辑表达式
\3. 关系表达式
\4. 赋值表达式
\5. 条件表达式
\6. 位运算表达式
\7. 成员运算表达式
\8. 身份运算表达式
十二、语句 标准的语句写法是每一个语句结束以后 用分号结尾
例如x = 10;,但是python不需要分号
语句分为单行语句和多行语句
1.if语句 1 2 3 4 5 6 7 8 9 10 11 if 1 == 1 : print ("1 == 1" ) else : print ("1 != 1" ) if 1 == 1 : print ("1 == 1" ) elif 1 == 2 : print ("1 == 2" ) else : print ("1 != 1" )
2.循环语句 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 for i in range (2 , 10 ,2 ): print (i) i = 1 while i <= 10 : print (i) i += 1 else : print ("循环结束" )
3.break和continue语句 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 i = 0 while True : print (i) i += 1 if i == 5 : break for i in range (10 ): if i == 5 : break print (i) for i in range (10 ): if i == 5 : continue print (i)
4.推导式 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 x2 = [i**2 for i in range (1 , 11 ) if i%2 == 0 ] print (x2)x3 = tuple (i**2 for i in range (1 , 11 )) print (x3)key = ['a' , 'b' , 'c' , 'd' , 'e' , 'f' , 'g' , 'h' , 'i' , 'j' , 'k' ] x4 = {key[i]: i**2 for i in range (1 , 11 )} print (x4)x5 = {i**2 for i in range (1 , 11 )} print (x5)
运行结果:
[4, 16, 36, 64, 100] (1, 4, 9, 16, 25, 36, 49, 64, 81, 100) {‘b’: 1, ‘c’: 4, ‘d’: 9, ‘e’: 16, ‘f’: 25, ‘g’: 36, ‘h’: 49, ‘i’: 64, ‘j’: 81, ‘k’: 100} {64, 1, 4, 36, 100, 9, 16, 49, 81, 25}
5.with语句 1 2 3 4 5 6 7 8 9 10 11 12 13 with open ("test.txt" ,"r" ) as f: print (f) for line in f: print (line) f = open ("test.txt" ,"r" ) print (f)for line in f: print (line) f.close()
十三、函数 1.声明函数 1 2 3 4 5 6 7 def f1 (): print ("f1运行" ) f1() def f2 (x1,x2 ): print (x1+x2) f2(5 ,6 )
return会让函数停止执行并返回结果
1 2 3 4 def f2 (x1,x2 ): return x1+x2 a = f2(6 ,6 ) print (a)
运行结果:
f1运行 11 12
2.参数的数量和位置 1 2 3 4 5 6 7 8 9 10 11 def add (a, b ): return b + a print (add(2 , 3 ))
3.关键字参数 先定义默认值,然后再调用时传入关键字参数
1 2 3 4 5 def my_func (a, b, c=0 , d=0 ): return a + b + c + d print (my_func(1 , 2 , 3 , 4 )) print (my_func(1 , 2 , d=4 ))
4.元组解包参数 1 2 3 4 5 6 7 8 9 10 11 def fn (a,b,c,*args ): print (a,b,c) print (args,type (args)) fn(1 ,2 ,3 ) fn(5 ,3 ,6 ,8 ,9 ,5 ,4 ,8 ) def fn (*args ): print (*args) fn(5 ,6 ,8 )
运行结果:
1 2 3 () <class ‘tuple’> 5 3 6 (8, 9, 5, 4, 8) <class ‘tuple’> 5 6 8
5.字典解包参数 1 2 3 4 5 6 def fn (a,b,**args ): print (a,b) print (args,type (args)) fn(20 ,30 ) fn(10 ,20 ,name="jack" ,age = "18" )
运行结果:
20 30 {} <class ‘dict’> 10 20 {‘name’: ‘jack’, ‘age’: ‘18’} <class ‘dict’>
**args 与 *kwargs一起使用,可以接收任意数量的位置参数和关键字参数。
1 2 3 4 5 def my_func (*args, **kwargs ): print (args) print (kwargs) my_func(1 , 2 , 3 , a=4 , b=5 )
运行结果:
(1, 2, 3) {‘a’: 4, ‘b’: 5}
只要是有下标的参数都可以解包
1 2 3 4 5 6 7 8 9 10 11 12 my_list = [1 , 2 , 3 ] my_func(*my_list) my_dict = {'a' : 1 , 'b' : 2 , 'c' : 3 } my_func(**my_dict) my_tuple = (1 , 2 , 3 ) my_func(*my_tuple) my_str = '123' my_func(*my_str)
6.占位符 1 2 3 4 5 def my_func (x, *, y ): print (x, y) my_func(1 , y=2 )
7.匿名函数lambda 1 2 3 4 5 6 fn=lambda x,y:x+y print (fn(2 ,3 ))fn = lambda x:"奇数" if x%2 ==1 else "偶数" print (fn(11 ))print (fn(2 ))
案例1:判断是否是闰年
1 2 3 4 5 6 7 8 def is_leap (year ): if (year%4 )==0 and (year%100 )!=0 : return True elif (year%400 )==0 : return True else : return False print (is_leap(2024 ))
案例2:按比例划分数据集
1 2 3 4 5 6 7 8 9 def train_test_split (data,train_size = 0.8 ): train_data = data[:int (len (data)*train_size)] test_data = data[int (len (data)*train_size):] return train_data,test_data data = [1 ,2 ,3 ,4 ,5 ,6 ,7 ,8 ,9 ,10 ] train_data,test_data = train_test_split(data,0.8 ) print (train_data)print (test_data)
运行结果:
[1, 2, 3, 4, 5, 6, 7, 8] [9, 10]
函数分为三种:
官方内置函数,第三方函数,自己写的函数
8.官方内置函数 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 x = [-10 ,0 ,30 ,-2 ] re = all (x) print (re)print (any (x))print (sum (x))def fn (x ): return x**2 print (sorted (x,key = fn))print ([i for i in reversed (x)])fn = 100 print (callable (fn))fn = lambda x,y:x+y print (callable (fn))x = [10 ,20 ,30 ,40 ,50 ] y = [40 ,50 ,60 ] print ([i for i in zip (x,y)])exec ("print('hello')" )
运行结果:
False True 18 [0, -2, -10, 30] [-2, 30, 0, -10] False True [(10, 40), (20, 50), (30, 60)] hello
9.globals和locals() globals()返回值是一个字典,字典的key就是当前python环境全局变量的名字
1 2 3 x = 10 y = 20 print (globals ())
运行结果是一大串字典
locals()返回值是一个字典,字典的key就是当前函数的局部变量的名字
1 2 3 def fn (x,y ): print (locals ()) fn(1 ,2 )
运行结果:
{‘x’: 1, ‘y’: 2}
10.filter函数 filter(函数,可迭代对象),传入两个参数:函数和可迭代对象,返回一个经过函数筛选后的可迭代对象
1 2 3 x = [1 ,2 ,2 ,3 ,5 ,6 ,4 ,8 ,5 ,2 ] x2 = filter (lambda el:el%2 ==1 ,x) print (list (x2))
实现:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 def myfilter (fn,x ): x2 = [] for i in x: if fn(i) ==True : x2.append(i) else : continue return x2 def fn (x ): if x%2 ==0 : return True else : return False re = myfilter(fn,[1 ,2 ,2 ,3 ,5 ,6 ,4 ,8 ,5 ,2 ]) print (re)
运行结果:
[2, 2, 6, 4, 8, 2]
11.map函数 map(函数,可迭代对象),与filter不同的是不需要进行筛选,直接经过函数映射到可迭代对象中
1 2 3 4 x = [1 ,2 ,2 ,3 ,5 ,6 ,4 ,8 ,5 ,2 ] def fn (x ): return x**2 print (list (map (fn,x)))
实现
1 2 3 4 5 6 7 8 9 def mymap (fn,x ): x2 = [] for i in x: x2.append(fn(i)) return x2 def fn (x ): return x**2 re = mymap(fn,[1 ,2 ,2 ,3 ,5 ,6 ,4 ,8 ,5 ,2 ]) print (re)
运行结果:
[1, 4, 4, 9, 25, 36, 16, 64, 25, 4]
12.reduce函数 reduce(函数,可迭代对象,初始值)
reduce()函数会对可迭代对象中的元素进行累积操作,并将结果作为第一个参数传递给函数,然后再将结果和第二个参数传递给函数,以此类推,直到可迭代对象中的所有元素都被处理完。最后,reduce()函数返回累积结果。
1 2 3 4 5 6 7 from functools import reducex = [1 ,2 ,4 ,3 ,5 ,6 ,4 ,8 ,5 ,2 ] def fn (x1,x2 ): print (x1,x2,"=====" ) return x1+x2 reduce(fn,x)
实现:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 def myreduce (fn,x,start ): x1 = fn(start,x[0 ]) for i in range (len (x)-1 ): x1 = fn(x1,x[i+1 ]) return x1 def fn (x1,x2 ): print (x1,x2,"=====" ) return x1+x2 x = [1 ,2 ,4 ,3 ,5 ,6 ,4 ,8 ,5 ,2 ] myreduce(fn,x,0 )
运行结果:
0 1 ===== 1 2 ===== 3 4 ===== 7 3 ===== 10 5 ===== 15 6 ===== 21 4 ===== 25 8 ===== 33 5 ===== 38 2 =====
13.作用域 作用域只针对函数,函数内部可以访问函数内部和外部的变量,但是函数外部不能访问函数内部的变量
1 2 3 4 5 6 7 8 9 10 a = 100 def fn (): q = 10 a = 20 print (a) print (q) return a+q print (fn())print (a)
运行结果:
20 10 30 100
1 2 b = [1 ,2 ,3 ,4 ,5 ,lambda x:x+1 ] print (b[5 ](5 ))
运行结果:
6
函数调用在A作用域 定义在B作用域,函数无论在哪个作用域中执行,一定是他定义的作用域下执行代码
1 2 3 4 5 6 7 8 9 a = 100 def fm (): print (a) def fn (): a = 200 fm() fn()
运行结果:
100
函数也是一种数据
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 def f1 (): a = 100 def f2 (): print (a) return f2 a = 200 re = f1() re()
作用域案例:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 def fun (n = None ,o = None ): print (o) return {"fun" :lambda m:fun(m,n)} a = fun(0 ) a["fun" ](1 ) a["fun" ](2 ) a["fun" ](3 ) b = fun(0 )["fun" ](1 )["fun" ](2 )["fun" ](3 ) c = fun(0 )["fun" ](1 ) c["fun" ](2 ) c["fun" ](3 )
运行结果:
None 0 0 0 None 0 1 2 None 0 1 1
14.修改变量值 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 a = 10 def fn (): global a print (a) a = 20 fn() print (a)a = 10 def fn (): global a a = 20 def fm (): global a print (a) a = 30 fm() fn() a = 10 def fn (): a = 20 def fm (): nonlocal a print (a) a = 30 fm() fn()
运行结果:
10 20 20 20
15.内建作用域
运行结果:
main
16.递归 1 2 3 4 5 6 7 8 def f (a ): if a > 5 : return a else : return f(a+1 ) r = f(0 ) print (r)
运行结果:
6
函数返回值是一种数据,函数也是一种数据
1 2 3 4 def fn (): return 1 +1 print (type (fn))print (type (fn()))
运行结果:
<class ‘function’> <class ‘int’>
16.回调函数 callback 把一个函数传入另外一个函数,传入的函数就是回调函数
定义一个工具函数,传入两个数和一个函数,调用传入的函数并返回结果
a,b可以是数据也可以是字符串,func必须是函数
1 2 3 4 5 6 7 8 9 10 11 def add (a,b ): return a+b def sub (a,b ): return a-b def calculate (a,b,func ): return func(a,b) print (calculate(5 ,3 ,add)) print (calculate(5 ,3 ,sub))
回调函数怎么体现:
遍历:把一个数据容器中的数据全部拿出来调用
设计一个工具函数:遍历列表中的所有元素,找出奇数拿来使用,但是这个工具自己并不适用
而是交给业务函数(回调)使用
1 2 3 4 5 6 7 8 9 10 def find_odd (arr,cb ): for el in arr: if el%2 ==1 : cb(el) x = [2 ,5 ,6 ,8 ,9 ,7 ] def print_odd (el ): print ("找到一个奇数:" ,el) find_odd(x,print_odd) find_odd(x,lambda m:print (m**2 ))
运行结果:
找到一个奇数: 5 找到一个奇数: 9 找到一个奇数: 7 25 81 49
17.闭包函数 block 函数内部有函数,内部的那个函数就是闭包函数
1.由于函数有作用域,而且多个函数的作用域是相互独立的
使用闭包函数把函数的值单独保存,让变量不要相互污染
2.由于函数调用和定义的作用域可以不是同一个,并且函数调用时是在定义的作用域中执行的
因此闭包函数可以在函数外部访问函数内部的变量
1 2 3 4 5 6 7 8 9 10 11 def alipay (): money_in = 100 def tool (): money_in = 300 print (money_in) return tool re = alipay() re() money_out = 200 print (money_out)
案例
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 def alipay (): money1 = 200 def tool (pwd,new_money ): nonlocal money1 if pwd == 123 : money1 = new_money print (money1) def withdraw (pwd,amount ): nonlocal money1 if pwd == 123 : money1 -= amount print (money1) return tool,withdraw def meituan (): tool,withdraw = alipay() tool(123 ,666 ) withdraw(123 ,50 ) meituan()
运行结果:
666 616
十四、装饰器 参考:一文搞懂Python装饰器(通俗易懂) - 知乎
装饰器相当于一个闭包的调用,但是不同的是相较于Alipay的案例,不需要多余构建re变量,直接用@装饰器名字的方式来调用,相当于一种方便的写法
装饰器本质是回调函数和闭包函数的结合
装饰器本身是一个函数,把装饰的函数作为参数输入,然后吧调用封装在内部的闭包中,返回值那个闭包
不带参数的装饰器
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 def fn (): print ("fn函数的业务是答应一句话:未来业务可能有很多行代码" ) def decorator (cb ): def block1 (): print ("装饰器执行的代码:怎么装饰由业务决定" ) cb() print ("装饰器可以继续装饰:怎么装饰由业务决定" ) return block1 @decorator def fn2 (): print ("fn2函数的业务是打印一句话:未来就是具体业务代码" ) fn2()
运行结果:
装饰器执行的代码:怎么装饰由业务决定 fn2函数的业务打印是一句话:未来就是具体业务代码 装饰器可以继续装饰:怎么装饰由业务决定
带参数的装饰器:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 def my_decorator (func ): def wrapper (*args, **kwargs ): print ("Before calling the function" ) func(*args, **kwargs) print ("After calling the function" ) return wrapper @my_decorator def my_function (x, y ): print ("The sum of" , x, "and" , y, "is" , x+y) return x + y my_function(2 , 3 )
运行结果:
Before calling the function The sum of 2 and 3 is 5 After calling the function
作用:
*日志记录 * :在函数执行前后自动添加日志记录,方便调试和监控程序行为。
*性能测试 * :装饰器可以用来测量函数的执行时间,帮助识别性能瓶颈。
*权限验证 * :在Web开发中,装饰器可以用于检查用户是否有权访问某个资源或执行特定操作。
*缓存 * (Memoization) :通过装饰器实现函数结果的缓存,避免重复计算相同的输入值,从而提高效率。
十五、面向对象 1.类和对象的语法 定义一个类
1 2 3 4 5 6 7 8 9 class Person : name = "张三" age = 18 life = 1 def fn (self,num ): print ("类中的函数叫做方法,参数是" ,num) print (Person,type (Person))
用这个类创造对象
1 2 p1 = Person() print (p1,type (p1))
对象内部保存了很多数据,想要访问需要通过成员名
语法:对象名.成员名
1 2 3 4 5 6 7 print (p1.name,p1.age,p1.life)p1.fn(1 ) p2 = Person() p2.fn(2 )
运行结果:
<class ‘__main__.Person’> <class ‘type’> <__main__.Person object at 0x00000187F9C19940> <class ‘__main__.Person’> 张三 18 1 类中的函数叫做方法,参数是 1 类中的函数叫做方法,参数是 2
2.init 实用类创建对象时,可以初始化对象的成员的值
但是在Python当中__init__并不是构造函数,__new__才是
__init__是一个魔术方法,是一个特殊的函数,会在创建对象时调用
1 2 3 4 5 6 7 8 9 10 11 12 13 14 class Teacher : def __init__ (self,name,age ): print ("__init__ name:" ,name,"年龄:" ,age) self .n = name self .a = age def fn (self,name,age ): print ("fn name:" ,name,"年龄:" ,age) t1 = Teacher("xiaoming" ,18 ) t1.fn("xiaoming" ,18 ) t1.a
运行结果:
init name: xiaoming 年龄: 18 fn name: xiaoming 年龄: 18
类每次创建对象时,创建对象有同样的属性和方法,而有一部分是创建的时候赋的值,有一部分创建的时候值一样
1 2 3 4 5 6 7 8 9 10 11 class Game_person : life = 1 def __init__ (self,name,rank ): self .name = name self .rank = rank g1 = Game_person("boss" ,2000 ) g2 = Game_person("npc" ,100 ) print (g1.name,g1.rank)print (g2.name,g2.rank)
运行结果:
boss 2000 npc 100
3.对象语法 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 class Box : x = 100 def __init__ (self,y ): self .y = 200 def change_y (self,new_y ): print ("调用函数前" ,self .y ) self .y = new_y print ("调用函数后" ,self .y ) b1 = Box(99 ) b1.x = 200 print (b1.x)b2 = Box(98 ) print (b2.x)b3 = Box(97 ) print (b3.y)b3.y = 1 print ("直接修改后" ,b3.y)b3.change_y(2 ) print (b3.y)
运行结果:
200 100 200 直接修改后 1 调用函数前 1 调用函数后 2 2
4.对象的方法内部可以操作这个对象的属性和方法 1 2 3 4 5 6 7 8 9 10 class Person : def __init__ (self, name, age ): self .name = name self .age = age def say_hello (self ): print ("Hello, my name is {} and I am {} years old." .format (self .name, self .age)) p1 = Person("Alice" , 25 ) p1.say_hello()
运行结果:
Hello, my name is Alice and I am 25 years old.
5.对象的方法可以传入参数,也可以返回值。 1 2 3 4 5 6 7 8 9 10 class Box : count = 100 def __init__ (self,m ): self .m = m def cal_total (self,price ): return self .count*self .m*price b1 = Box(45 ) re = b1.cal_total(108 ) print (re)
运行结果:
486000
案例1
假设有一个ATM类 用这个类创建出来的对象就是一个取款机对象
atm对象有一个属性 是一个列表 里面装了很多对象,每一个对象就是一个Person类型的对象
有一个属性 是一个数字 保存了余额
有一个方法可以往ATM里面添加Person对象
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 class Person : def __init__ (self,name,card_num,phone_num ): self .name = name self .card_num = card_num self .phone_num = phone_num class ATM : money = 5000 persons = [] def add_person (self,person ): if person not in self .persons: self .persons.append(person) print ("添加成功" ) else : print ("该卡号已存在" ) atm = ATM() person1 = Person("张三" ,"123456" ,"13800138000" ) person2 = Person("李四" ,"654321" ,"13800138001" ) atm.add_person(person1) atm.add_person(person2) print (atm.persons[0 ].name)print (atm.persons[0 ].card_num)print (atm.persons[0 ].phone_num)
运行结果:
添加成功 添加成功 张三 123456 13800138000
案例2:
公司员工管理系统
设计一个公司员工管理系统,包含以下内容:
\1. 定义一个 Employee
类,包含以下属性:
- name
(姓名)
- position
(职位)
- salary
(薪水)
\2. 定义一个 Company
类,包含以下内容:
- 一个列表属性,用于存储 Employee
对象。
- 一个方法 hire_employee
,用于招聘新员工。
- 一个方法 fire_employee
,根据员工的姓名,解雇该员工。
- 一个方法 list_employees
,用于列出公司中所有员工的信息。
- 一个方法 total_salary
,计算公司所有员工的总薪水。
\3. 测试代码:
- 创建一个 Company
对象。
- 招聘几个员工。
- 列出所有员工。
- 解雇一个员工。
- 再次列出所有员工。
- 打印公司总薪水。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 class Employee : def __init__ (self,name,position,salary ): self .name = name self .position = position self .salary = salary class Company : Employee_lst = [] def hire_employee (self,Employee ): if Employee not in self .Employee_lst: self .Employee_lst.append(Employee) else : print ("已经添加该员工" ) def list_employees (self ): for Employee in self .Employee_lst: print ("name:" ,Employee.name,"position:" ,Employee.position,"salary:" ,Employee.salary) def total_salary (self ): salary_total = [] for Employee in self .Employee_lst: salary_total.append(int (Employee.salary)) return sum (salary_total) person1 = Employee("张三" ,"经理" ,"5000" ) person2 = Employee("李四" ,"客服" ,"3000" ) person3 = Employee("王五" ,"地推" ,"1000" ) ali = Company() ali.hire_employee(person1) ali.hire_employee(person2) ali.hire_employee(person3) ali.list_employees() salary = ali.total_salary() print (salary)
运行结果:
name: 张三 position: 经理 salary: 5000 name: 李四 position: 客服 salary: 3000 name: 王五 position: 地推 salary: 1000 9000
6.类属性和类方法 1 2 3 4 5 6 7 8 9 10 11 12 13 14 class qox : x = 100 def fn (self ): print (qox.x) print (qox.x)b1 = qox() print (b1.x)b1.x = 500 print (b1.x)print (qox.x)b1.fn()
运行结果:
100 100 500 100 100
7.类属性和类方法 它接收类本身作为第一个参数(通常命名为 cls),而不是实例(self)。
类方法可以访问类的属性和方法,但不能访问实例的属性
类变量是在类的定义中直接定义的变量,而不是在类的 init 方法或其他实例方法中定义的。
类变量属于类本身,而不是属于类的某个实例
1 2 3 4 5 6 7 8 9 10 11 12 13 14 class qox : x = 100 def fn (self ): print (qox.x) print (qox.x)b1 = qox() print (b1.x)b1.x = 500 print (b1.x)print (qox.x)b1.fn()
显式的指定类方法
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 class Box : x = 100 def __init__ (self,y ): self .y = y def fn (self ): print (self .x) @classmethod def fm (cls ): print ("fm被调用" ) print (cls.x) b1 = Box(100 ) print (b1.x)print (b1.y)b1.fn() b1.fm() Box.fm()
案例:类方法常可以作为工厂方法
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 class single : instance = None @classmethod def share_instance (cls ): if cls.instance is None : cls.instance = single() return cls.instance else : return cls.instance s1 = single.share_instance() s2 = single.share_instance() print (s1)print (s2)o1 = single() o2 = single() print (id (o1))print (id (o2))
批量创建对象
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 class student : def __init__ (self, name, age ): self .name = name self .age = age @classmethod def create_students (cls,num ): arr = [] for i in range (num): arr.append(cls(f"student{i} " , i)) return arr s1 = student("Alice" , 20 ) s2 = student("Bob" , 21 ) print (s1.name, s1.age)print (s2.name, s2.age)students = student.create_students(10 ) students[0 ].name = "jack" students[0 ].age = 22 print (students[0 ].name, students[0 ].age)
8.静态方法 静态方法通常用于实现一些与类无关的工具函数,这些函数不需要访问类或实例的属性。
它们可以被类或实例调用,但不会影响类或实例的状态。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 class Box : count = 0 def fn (self ): print ("fn普通方法" ) @classmethod def fm (cls ): print ("fm类方法" ) @staticmethod def fz (): print ("fn静态方法" ) @staticmethod def sigmod (x ): return 1.0 /(1.0 +math.exp(-x)) Box.fm() Box.fz() b1 = Box() b1.fz() re = Box.sigmod(10 ) print (re)
9.构造方法 静态方法__new__ 方法负责创建并返回类的新实例,而 init 方法则用于初始化实例。
1 2 3 4 5 6 7 8 9 10 class Box : def __new__ (self ): print (self ) return super ().__new__(self ) def __init__ (self ): self .width = 0 b1 = Box() print (b1.width)print (b1,Box)
10.魔术方法 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 class Person : def __init__ (self, name, age ): self .name = name self .age = age def __str__ (self ): return f"Person(name={self.name} , age={self.age} )" def __repr__ (self ): return f"Person(name={self.name} , age={self.age} )" def __delitem__ (self ): print ("删除对象" ) del self .name def __add__ (self, other ): return Person(f"{self.name} +{other.name} " , self .age + other.age) def __sub__ (self, other ): return self .age - other.age def __iter__ (self ): return iter ([self .name, self .age]) p = Person("Alice" , 25 ) print (p)print (repr (p))p2 = Person("Bob" , 30 ) p3 = p + p2 print (p3)print (p2 - p)print (type (p))for item in p: print (item)
11.比较常用的魔术方法 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 class Images : def __init__ (self,path ): self .path = path self .arr = ["6.jpg" ,"5.jpg" ,"4.jpg" ,"3.jpg" ,"2.jpg" ,"1.jpg" ] def __len__ (self ): return len (self .arr) def __getitem__ (self,index ): print (index) return self .arr[index] def __setitem__ (self,index,value ): print (index,value) def __call__ (self, *args, **kwargs ): print ("调用了__call__方法" ,args,kwargs) imgs = Images("./imgs" ) count = len (imgs) print (count)print (imgs[2 ])print ("===========" )imgs[1 ] = 2 print ("===========" )print ("__setitem__" ,imgs[1 ])imgs(1 ,2 ,3 ,a=1 ,b=2 )
12.继承 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 class Person : def __init__ (self, name, age ): self .name = name self .age = age def eat (self ): print (f"{self.name} 今年{self.age} 岁,正在吃饭" ) p1 = Person("张三" , 20 ) p1.eat() class Student (Person ): def __init__ (self, name, age, school ): super ().__init__(name, age) self .school = school s1 = Student("李四" , 21 , "清华大学" ) s1.eat() print (s1.school)
运行结果:
张三今年20岁,正在吃饭 李四今年21岁,正在吃饭 清华大学
13.覆盖-重写 父类已经定义了一个方法,子类要将这个方法重新修改,就叫重写
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 class Animal : def __init__ (self,name ): self .name = name def eat (self ): print ("Animal的eat方法,{} is eating" .format (self .name)) def sleep (self ): print ("Animal的sleep方法,{} is sleeping" .format (self .name)) class Dog (Animal ): def __init__ (self, name,age ): super ().__init__(name) self .age = age def say (self ): print ("Dog的say方法,{} is barking" .format (self .name)) def eat (self ): print ("Dog重写了Animal的eat方法,{} is eating" .format (self .name)) dog = Dog("旺财" , 3 ) print (dog.name)print (dog.age)dog.sleep() dog.say() dog.eat()
14.多台 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 class Animal : def eat (self ): print ("动物会吃东西" ) class Dog (Animal ): def eat (self ): print ("狗会吃骨头" ) class Cat (Animal ): def eat (self ): print ("猫会吃鱼" ) def eat (animal ): animal.eat() dog = Dog() cat = Cat() eat(dog) eat(cat) print (isinstance (dog, Animal))print (isinstance (dog, Dog))
15.私有属性 不同于类属性,在属性前面加__表示只能在类中调用这个属性
1 2 3 4 5 6 7 8 9 10 11 12 13 class Person : __name = 'jack' def __init__ (self, __age ): self .__age = __age def fn (self ): print ("私有属性只能在类内部访问" ) print ("私有属性:" , self .__name) print ("私有属性:" , self .__age) p = Person(25 ) p.fn()
16.重载魔术方法 下面重新定义了Python中的加减乘除,实质就是改写了底层的魔术方法
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 class Box : def __init__ (self, width, height ): self .width = width self .height = height def __add__ (self, other ): return self .width + self .height + other.width + other.height def __sub__ (self, other ): return self .width - self .height - other.width - other.height def __mul__ (self, other ): return self .width * self .height * other.width * other.height def __truediv__ (self, other ): return self .width / self .height / other.width / other.height def __floordiv__ (self, other ): return self .width // self .height // other.width // other.height b1 = Box(2 , 3 ) b2 = Box(4 , 5 ) print (b1 + b2)print (b1 - b2)print (b1 * b2)print (b1 / b2)print (b1 // b2)
17.super()方法 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 class Box : x = 5 def fn (self ): print ("这是Box类的fn方法" ) def fm (self ): print ("这是Box类的fm方法" ) class Box2 (Box ): x = 10 def fn (self ): super ().fn() print ("这是Box2类的fn方法" ) super ().fm() print ("这是Box2类的fm方法" ) b = Box2() b.x = 400 super (Box2, b).fn() super (Box2, b).x
十六、迭代器和生成器 1.迭代器iter 全局函数iter 可以把一个可迭代对象转换成一个迭代器,全局函数next 他可以迭代下一次迭代器中的数据,for 循环可以连续调用next
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 arr = [10 ,20 ,30 ,40 ,50 ] iterator = iter (arr) re1 = next (iterator) print (re1)re2 = next (iterator) print (re2)re3 = next (iterator) print (re3)for el in iterator: print (el,"====================" )
案例:
实现数据加载器的底层核心源代码,有一个数据容器,里面有1000条数据,封装一个可迭代对象,这个对象迭代一次就取出这个列表的n条数据,n = 8
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 class myData : def __init__ (self,data ): self .data = data self .index = -1 def __iter__ (self ): return self def __next__ (self ): while self .index < len (self .data)//8 : self .index += 1 return self .data[self .index * 8 :(self .index+1 ) * 8 ] data = myData(["a" , "b" , "c" , "d" , "e" , "f" , "g" , "h" , "i" , "j" , "k" , "l" , "m" , "n" , "o" , "p" , "q" , "r" , "s" , "t" , "u" , "v" , "w" , "x" , "y" , "z" ]) data_loader = iter (data) re = next (data_loader) print (re)re = next (data_loader) print (re)re = next (data_loader) print (re)
2.生成器yield yield关键字在函数内部 会让函数暂时生成结果,但是函数还没有运行完毕,并且这个函数调用的代码的后面的代码会正常执行
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 def my_gen (): print ("start" ) yield 1 print ("middle" ) yield 2 print ("end" ) yield 3 re = my_gen() print (next (re),"===========" ) print (next (re),"===========" )print (next (re),"===========" )
案例:
实现range函数源代码
1 2 3 4 5 6 7 8 9 10 11 def myrange (start,end,step ): i = start - step while True : i += step if i >= end: break yield i for el in myrange(0 ,11 ,2 ): print (el)
十七、异常处理 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 try : arr = [100 ,20 ] x = arr[100 ] print (x) except ValueError: print ("数组类型错误" ,ValueError) except IndexError as e: print ("数组越界" ,e) else : print ("没有异常" ) finally : print ("不管有没有报错都执行finally" ) print ("后面的代码" )
运行结果:
数组越界 list index out of range 不管有没有报错都执行finally 后面的代码
常见的几种except选项:
1 2 3 4 5 6 7 8 9 10 11 | ZeroDivisionError | 除(或取模)零 (所有数据类型) | | ----------------- | ---------------------------- | | ValueError | 传入无效的参数 | | AssertionError | 断言语句失败 | | StopIteration | 迭代器没有更多的值 | | IndexError | 序列中没有此索引(index) | | IndentationError | 缩进错误 | | OSError | 输入/输出操作失败 | | ImportError | 导入模块/对象失败 | | NameError | 未声明/初始化对象 (没有属性) | | AttributeError | 对象没有这个属性 |
或者直接不写这个错误类型
1 2 3 4 5 6 try : print (3 / 0 ) except : print ("报错" ) else : print ("没错" )
运行结果:
报错
主动抛出错误:
1 2 3 4 5 6 7 8 9 10 11 def fn (): x = 10 if 5 <x<6 : print (x) else : raise ValueError("x不在范围内" ) try : fn() except ValueError as e: print (e) print ("后续代码" )
运行结果:
x不在范围内 后续代码
十八、模块与包 1 2 3 4 5 6 7 8 9 import model1 as m1from model2 import areafrom model2 import perimeter as periprint (m1.is_prime(7 ))print (m1.is_palindrome("racecar" ))print (area(5 , 6 ))print (peri(5 , 6 ))
1. file__和__name 这两个全局变量保存的是字符串
1 2 3 print (__file__)print (__name__)
运行结果:
d:\桌面\华清\基础语法\code\Python基础语法\21-模块与包.py main
十九、内置函数 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 import randomimport timeimport osif __name__ != "__main__" : re1 = random.random() print ("re1" ,re1) re2 = random.randint(-5 ,6 ) print ("re2" ,re2) arr = [1 ,2 ,3 ,4 ,5 ,6 ,7 ,8 ,9 ] re3 = random.choice(arr) print ("re3" ,re3) re4 = random.shuffle(arr) print ("re4" ,re4) print (arr) def time_fn (): t = time.time() print (t) for i in range (3 ): time_fn() time.sleep(1 ) print (time.localtime()) print (time.localtime().tm_mday) print (time.strftime("%y年%m-%d %H:%M:%S" )) def os_fn (): path = os.getcwd() print (f"====={path} =======" ) re = os.path.join(path,"./img" ,"a.jpg" ) print (re) re1 = os.path.realpath(re) print (re1) os.mkdir("./code/img" ) if __name__ == "__main__" : os_fn()
总结 大纲已完结,后续会有补充