- 1 函数的基本使用
复习十五分钟: 1、编写代码实现功能tail -f access.log f.seek() 应用程序(文件对象/文件句柄1) 应用程序(文件对象/文件句柄2) 操作系统(真正的文件)a.txt z 计算机硬件(硬盘空间) 2、代码展示文件修改的两种方式 方式一: with open('源文件',mode='r') as src_f: res=src_f.read() new_res=修改res with open('源文件',mode='w') as dst_f: dst.write(new_res) 方式二: with open('源文件',mode='r') as src_f,open('临时文件',mode='w') as dst_f: for line in src_f: new_line=修改line dst.write(new_line) 删除源文件 将临时文件重命名为源文件的名字 3、定义函数的语法是什么? 函数-》盛放功能(一堆代码)的容器 内置函数:python解释已经定义好了,直接调用即可 open() input() 自定义函数: 先定义 后调用 def 函数名(参数1,参数2,...): """文档注释""" 代码块 return 值 4、函数的基本使用遵循的原则是? 5、简述函数定义阶段与调用阶段发生的事情 定义阶段: 1、申请内存空间将函数体代码存放起来,然后将内存地址绑定给函数名 函数名=函数的内地址 2、只检测语法,不执行代码 调用函数:函数名() 1、先通过函数名(变量名)找函数的内存 2、加括号触发函数体代码的运行 6、代码展示定义函数的三种形式 def func(): pass func() def func(x,y): pass func(1,2) def func(): pass 7、代码展示调用函数的三种形式 # 语句形式:只运行功能 func(1,2) func() # 表达式形式 res=func(1,2) res=func(1,2)*10 # 参数传入 func(func(1,2),10) 8、return返回值的三种形式是什么? None: 没有return return return None 一个值: return 值 多个值 return 值1,值2,值3 强调: return是函数结束的标志,函数内可以有多个return,但只要执行一个 整个函数就会立刻结束,并且将该return后的值作为本次运行的结果返回 上节课复习 今日内容:函数参数的使用 一 形参与实参介绍 二 形参与实参的具体使用 2.1 位置参数 2.2 关键字参数 2.3 默认参数 2.4 可变长度的参数(*与**的用法) 2.4.1 可变长度的位置参数 2.4.2 可变长度的关键字参数 2.5 命名关键字参数(了解) 2.6 组合使用(了解)
""" @作者: egon老湿 @微信:18611453110 @专栏: https://zhuanlan.zhihu.com/c_1189883314197168128 1、什么是函数 函数就相当于具备某一功能的工具 函数的使用必须遵循一个原则: 先定义 后调用 2、为何要用函数 1、组织结构不清晰,可读性差 2、代码冗余 3、可维护性、扩展性差 3、如何用函数 先定义 三种定义方式 后调用 三种调用方式 返回值 三种返回值的形式 """ # 一、先定义 # 定义的语法 ''' def 函数名(参数1,参数2,...): """文档描述""" 函数体 return 值 ''' # 形式一:无参函数 # def func(): # # x # # print( # print('哈哈哈') # print('哈哈哈') # print('哈哈哈') # 定义函数发生的事情 # 1、申请内存空间保存函数体代码 # 2、将上述内存地址绑定函数名 # 3、定义函数不会执行函数体代码,但是会检测函数体语法 # 调用函数发生的事情 # 1、通过函数名找到函数的内存地址 # 2、然后加口号就是在触发函数体代码的执行 # print(func) # func() # 示范1 # def bar(): # bar=函数的内存地址 # print('from bar') # # def foo(): # # print(bar) # bar() # print('from foo') # # foo() # 示范2 # def foo(): # # print(bar) # bar() # print('from foo') # # def bar(): # bar=函数的内存地址 # print('from bar') # # foo() # 示范3 # def foo(): # # print(bar) # bar() # print('from foo') # # foo() # # def bar(): # bar=函数的内存地址 # print('from bar') # 形式二:有参函数 # def func(x,y): # x=1 y=2 # print(x,y) # func(1,2) # 形式三:空函数,函数体代码为pass def func(x, y): pass # 三种定义方式各用在何处 # 1、无参函数的应用场景 # def interactive(): # name=input('username>>: ') # age=input('age>>: ') # gender=input('gender>>: ') # msg='名字:{} 年龄:{} 性别'.format(name,age,gender) # print(msg) # # interactive() # interactive() # interactive() # interactive() # 2、有参函数的应用场景 # def add(x,y): # 参数-》原材料 # # x=20 # # y=30 # res=x + y # # print(res) # return res # 返回值-》产品 # # # add(10,2) # res=add(20,30) # print(res) # 3、空函数的应用场景 # def auth_user(): # """user authentication function""" # pass # # def download_file(): # """download file function""" # pass # # def upload_file(): # """upload file function""" # pass # # def ls(): # """list contents function""" # pass # # def cd(): # """change directory""" # pass # 二、调用函数 # 1、语句的形式:只加括号调用函数 # interactive() # add(1,2) # 2、表达式形式: # def add(x,y): # 参数-》原材料 # res=x + y # return res # 返回值-》产品 # 赋值表达式 # res=add(1,2) # print(res) # 数学表达式 # res=add(1,2)*10 # print(res) # 3、函数调用可以当做参数 # res=add(add(1,2),10) # print(res) # 三、函数返回值 # return是函数结束的标志,即函数体代码一旦运行到return会立刻 # 终止函数的运行,并且会将return后的值当做本次运行的结果返回: # 1、返回None:函数体内没有return # return # return None # # 2、返回一个值:return 值 # def func(): # return 10 # # res=func() # print(res) # 3、返回多个值:用逗号分隔开多个值,会被return返回成元组 def func(): return 10, 'aa', [1, 2] res = func() print(res, type(res)) # 函数参数的使用 """ @作者: egon老湿 @微信:18611453110 @专栏: https://zhuanlan.zhihu.com/c_1189883314197168128 """ # 一 形参与实参介绍 # 形参:在定义函数阶段定义的参数称之为形式参数,简称形参,相当于变量名 def func(x, y): # x=1,y=2 print(x, y) # 实参:在调用函数阶段传入的值称之为实际参数,简称实参,相当于变量值 # func(1,2) # 形参与实参的关系: # 1、在调用阶段,实参(变量值)会绑定给形参(变量名) # 2、这种绑定关系只能在函数体内使用 # 3、实参与形参的绑定关系在函数调用时生效,函数调用结束后解除绑定关系 # 实参是传入的值,但值可以是以下形式 # 形式一: # func(1,2) # 形式二: # a=1 # b=2 # func(a,b) # 形式三: # func(int('1'),2) # func(func1(1,2,),func2(2,3),333) # 二 形参与实参的具体使用 # 2.1 位置参数:按照从左到右的顺序依次定义的参数称之为位置参数 # 位置形参:在函数定义阶段,按照从左到右的顺序直接定义的"变量名" # 特点:必须被传值,多一个不行少一个也不行 # def func(x,y): # print(x,y) # func(1,2,3) # func(1,) # 位置实参:在函数调用阶段, 按照从左到有的顺序依次传入的值 # 特点:按照顺序与形参一一对应 # func(1,2) # func(2,1) # 2.2 关键字参数 # 关键字实参:在函数调用阶段,按照key=value的形式传入的值 # 特点:指名道姓给某个形参传值,可以完全不参照顺序 # def func(x,y): # print(x,y) # func(y=2,x=1) # func(1,2) # 混合使用,强调 # 1、位置实参必须放在关键字实参前 # func(1,y=2) # func(y=2,1) # 2、不能能为同一个形参重复传值 # func(1,y=2,x=3) # func(1,2,x=3,y=4) # 2.3 默认参数 # 默认形参:在定义函数阶段,就已经被赋值的形参,称之为默认参数 # 特点:在定义阶段就已经被赋值,意味着在调用阶段可以不用为其赋值 # def func(x,y=3): # print(x,y) # # # func(x=1) # func(x=1,y=44444) # def register(name,age,gender='男'): # print(name,age,gender) # # register('三炮',18) # register('二炮',19) # register('大炮',19) # register('没炮',19,'女') # 位置形参与默认形参混用,强调: # 1、位置形参必须在默认形参的左边 # def func(y=2,x): # pass # 2、默认参数的值是在函数定义阶段被赋值的,准确地说被赋予的是值的内存地址 # 示范1: # m=2 # def func(x,y=m): # y=>2的内存地址 # print(x,y # m=3333333333333333333 # func(1) # 示范2: # m = [111111, ] # # def func(x, y=m): # y=>[111111, ]的内存地址 # print(x, y) # # m.append(3333333) # func(1) # 3、虽然默认值可以被指定为任意数据类型,但是不推荐使用可变类型 # 函数最理想的状态:函数的调用只跟函数本身有关系,不外界代码的影响 # m = [111111, ] # # def func(x, y=m): # print(x, y) # # m.append(3333333) # m.append(444444) # m.append(5555) # # # func(1) # func(2) # func(3) # def func(x,y,z,l=None): # if l is None: # l=[] # l.append(x) # l.append(y) # l.append(z) # print(l) # func(1,2,3) # func(4,5,6) # new_l=[111,222] # func(1,2,3,new_l) # 2.4 可变长度的参数(*与**的用法) # 可变长度指的是在调用函数时,传入的值(实参)的个数不固定 # 而实参是用来为形参赋值的,所以对应着,针对溢出的实参必须有对应的形参来接收 # 2.4.1 可变长度的位置参数 # I:*形参名:用来接收溢出的位置实参,溢出的位置实参会被*保存成元组的格式然后赋值紧跟其后的形参名 # *后跟的可以是任意名字,但是约定俗成应该是args # def func(x,y,*z): # z =(3,4,5,6) # print(x,y,z) # func(1,2,3,4,5,6) # def my_sum(*args): # res=0 # for item in args: # res+=item # return res # # res=my_sum(1,2,3,4,) # print(res) # II: *可以用在实参中,实参中带*,先*后的值打散成位置实参 # def func(x,y,z): # print(x,y,z) # # # func(*[11,22,33]) # func(11,22,33) # # func(*[11,22]) # func(11,22) # # l=[11,22,33] # func(*l) # III: 形参与实参中都带* # def func(x,y,*args): # args=(3,4,5,6) # print(x,y,args) # func(1,2,[3,4,5,6]) # func(1,2,*[3,4,5,6]) # func(1,2,3,4,5,6) # func(*'hello') # func('h','e','l','l','o') # 2.4.2 可变长度的关键字参数 # I:**形参名:用来接收溢出的关键字实参,**会将溢出的关键字实参保存成字典格式,然后赋值给紧跟其后的形参名 # **后跟的可以是任意名字,但是约定俗成应该是kwargs # def func(x,y,**kwargs): # print(x,y,kwargs) # # func(1,y=2,a=1,b=2,c=3) # II: **可以用在实参中(**后跟的只能是字典),实参中带**,先**后的值打散成关键字实参 # def func(x,y,z): # print(x,y,z) # func(*{'x':1,'y':2,'z':3}) # func('x','y','z') # func(**{'x':1,'y':2,'z':3}) # func(x=1,y=2,z=3) # 错误 # func(**{'x':1,'y':2,}) # func(x=1,y=2) # func(**{'x':1,'a':2,'z':3}) # func(x=1,a=2,z=3) # III: 形参与实参中都带** # def func(x,y,**kwargs): # print(x,y,kwargs) # func(y=222,x=111,a=333,b=444) # func(**{'y':222,'x':111,'a':333,'b':4444}) # 混用*与**:*args必须在**kwargs之前 # def func(x,*args,**kwargs): # print(args) # print(kwargs) # # func(1,2,3,4,5,6,7,8,x=1,y=2,z=3) def index(x,y,z): print('index=>>> ',x,y,z) def wrapper(*args,**kwargs): #args=(1,) kwargs={'z':3,'y':2} index(*args,**kwargs) # index(*(1,),**{'z':3,'y':2}) # index(1,z=3,y=2) wrapper(1,z=3,y=2) # 为wrapper传递的参数是给index用的 # 原格式---》汇总-----》打回原形 # 2.5 命名关键字参数(了解) # 2.6 组合使用(了解)
1 1. 命名关键字参数(了解) 2 # 命名关键字参数:在定义函数时,*后定义的参数,如下所示,称之为命名关键字参数 3 # 特点: 4 # 1、命名关键字实参必须按照key=value的形式为其传值 5 # def func(x,y,*,a,b): # 其中,a和b称之为命名关键字参数 6 # print(x,y) 7 # print(a,b) 8 # 9 # # func(1,2,b=222,a=111) 10 11 # 示例 12 # def func(x,y,*,a=11111,b): 13 # print(x,y) 14 # print(a,b) 15 # 16 # func(1,2,b=22222) 17 18 # 2. 组合使用(了解) 19 # 形参混用的顺序:位置新参,默认形参,*args,命名关键字形参,**kwargs 20 # def func(x,y=111,*args,z,**kwargs): 21 # print(x) 22 # print(y) 23 # print(args) 24 # print(z) 25 # print(kwargs) 26 # 27 28 29 # 实参混用的顺序: 30 def func(x,y,z,a,b,c): 31 print(x) 32 print(y) 33 print(z) 34 print(a) 35 print(b) 36 print(c) 37 38 # func(111,y=222,*[333,444],**{'b':555,'c':666}) 39 # func(111,y=222,333,444,b=555,c=666) 40 41 # func(111,*[333,444],a=222,**{'b':555,'c':666}) 42 # func(111,333,444,a=222,b=555,c=66) 43 44 # func(111,*[333,444],**{'b':555,'c':666},a=222,) 45 func(111,3333,4444,b=555,c=666,a=222) 46 47 48 # func(1) 49 # func(x=1) 50 # func(1,x=1) 51 # func(*'hello') 52 # func(**{}) 53 # func(*'hell',**{}) 54 55 56 # 名称空间与作用域 57 # 一:名称空间namespacs:存放名字的地方,是对栈区的划分 58 # 有了名称空间之后,就可以在栈区中存放相同的名字,详细的,名称空间 59 # 分为三种 60 # 1.1 内置名称空间 61 # 存放的名字:存放的python解释器内置的名字 62 ''' 63 >>> print 64 <built-in function print> 65 >>> input 66 <built-in function input> 67 ''' 68 # 存活周期:python解释器启动则产生,python解释器关闭则销毁 69 70 71 # 1.2 全局名称空间 72 # 存放的名字:只要不是函数内定义、也不是内置的,剩下的都是全局名称空间的名字 73 # 存活周期:python文件执行则产生,python文件运行完毕后销毁 74 75 # import os 76 # 77 # x=10 78 # if 13 > 3: 79 # y=20 80 # if 3 == 3: 81 # z=30 82 # 83 # # func=函数的内存地址 84 # def func(): 85 # a=111 86 # b=222 87 88 # class Foo: 89 # pass 90 91 92 93 # 1.3 局部名称空间 94 # 存放的名字:在调用函数时,运行函数体代码过程中产生的函数内的名字 95 # 存活周期:在调用函数时存活,函数调用完毕后则销毁 96 # def func(a,b): 97 # pass 98 # 99 # func(10,1) 100 # func(11,12) 101 # func(13,14) 102 # func(15,16) 103 104 105 # 1.4 名称空间的加载顺序 106 # 内置名称空间>全局名称空间>局部名称空间 107 108 # 1.5 销毁顺序 109 # 局部名称空间>全局名空间>内置名称空间 110 111 # 1.6 名字的查找优先级:当前所在的位置向上一层一层查找 112 # 内置名称空间 113 # 全局名称空间 114 # 局部名称空间 115 116 # 如果当前在局部名称空间: 117 # 局部名称空间—>全局名称空间->内置名称空间 118 # # input=333 119 # 120 # def func(): 121 # # input=444 122 # print(input) 123 # 124 # func() 125 126 127 # 如果当前在全局名称空间 128 # 全局名称空间->内置名称空间 129 # input=333 130 # def func(): 131 # input=444 132 # func() 133 # print(input) 134 135 136 # 示范1: 137 # def func(): 138 # print(x) 139 # x=111 140 # 141 # func() 142 143 # 示范2:名称空间的"嵌套"关系是以函数定义阶段为准,与调用位置无关 144 # x=1 145 # def func(): 146 # print(x) 147 # 148 # 149 # def foo(): 150 # x=222 151 # func() 152 # 153 # foo() 154 155 # 示范3:函数嵌套定义 156 # input=111 157 # def f1(): 158 # def f2(): 159 # # input=333 160 # print(input) 161 # input=222 162 # 163 # f2() 164 # 165 # 166 # f1() 167 168 169 # 示范4: 170 # x=111 171 # def func(): 172 # print(x) # 173 # x=222 174 # 175 # func() 176 177 178 # 二:作用域-》作用范围 179 # 全局作用域:内置名称空间、全局名称空间 180 # 1、全局存活 181 # 2、全局有效:被所有函数共享 182 183 # x=111 184 # 185 # def foo(): 186 # print(x,id(x)) 187 # 188 # def bar(): 189 # print(x,id(x)) 190 # 191 # foo() 192 # bar() 193 194 # print(x,id(x)) 195 196 # 局部作用域: 局部名称空间的名字 197 # 1、临时存活 198 # 2、局部有效:函数内有效 199 200 # def foo(x): 201 # def f1(): 202 # def f2(): 203 # print(x) 204 205 206 207 # LEGB 208 # # builtin 209 # # global 210 # def f1(): 211 # # enclosing 212 # def f2(): 213 # # enclosing 214 # def f3(): 215 # # local 216 # pass
- 2 函数对象&嵌套&闭包
1 # 精髓:可以把函数当成变量去用 2 # func=内存地址 3 def func(): 4 print('from func') 5 6 7 # 1、可以赋值 8 # f=func 9 # print(f,func) 10 # f() 11 12 # 2、可以当做函数当做参数传给另外一个函数 13 # def foo(x): # x = func的内存地址 14 # # print(x) 15 # x() 16 # 17 # foo(func) # foo(func的内存地址) 18 19 # 3、可以当做函数当做另外一个函数的返回值 20 # def foo(x): # x=func的内存地址 21 # return x # return func的内存地址 22 # 23 # res=foo(func) # foo(func的内存地址) 24 # print(res) # res=func的内存地址 25 # 26 # res() 27 28 # 4、可以当做容器类型的一个元素 29 # l=[func,] 30 # # print(l) 31 # l[0]() 32 33 # dic={'k1':func} 34 # print(dic) 35 # dic['k1']() 36 37 # 函数对象应用示范: 38 # def login(): 39 # print('登录功能') 40 # 41 # 42 # def transfer(): 43 # print('转账功能') 44 # 45 # 46 # def check_banlance(): 47 # print('查询余额') 48 # 49 # def withdraw(): 50 # print('提现') 51 # 52 # 53 # def register(): 54 # print('注册') 55 # 56 # func_dic={ 57 # '1':login, 58 # '2':transfer, 59 # '3':check_banlance, 60 # '4':withdraw, 61 # '5':register 62 # } 63 # 64 # # func_dic['1']() 65 # 66 # 67 # while True: 68 # print(""" 69 # 0 退出 70 # 1 登录 71 # 2 转账 72 # 3 查询余额 73 # 4 提现 74 # 5 注册 75 # """) 76 # choice = input('请输入命令编号:').strip() 77 # if not choice.isdigit(): 78 # print('必须输入编号,傻叉') 79 # continue 80 # 81 # if choice == '0': 82 # break 83 # 84 # 85 # if choice in func_dic: 86 # func_dic[choice]() 87 # else: 88 # print('输入的指令不存在') 89 # 90 # # if choice == '1': 91 # # login() 92 # # elif choice == '2': 93 # # transfer() 94 # # elif choice == '3': 95 # # check_banlance() 96 # # elif choice == '4': 97 # # withdraw() 98 # # else: 99 # # print('输入的指令不存在') 100 101 102 # 修正 103 def login(): 104 print('登录功能') 105 106 107 def transfer(): 108 print('转账功能') 109 110 111 def check_banlance(): 112 print('查询余额') 113 114 115 def withdraw(): 116 print('提现')
1 # 函数嵌套 2 # 1、函数的嵌套调用:在调用一个函数的过程中又调用其他函数 3 # def max2(x,y): 4 # if x > y: 5 # return x 6 # else: 7 # return y 8 # 9 # 10 # def max4(a,b,c,d): 11 # # 第一步:比较a,b得到res1 12 # res1=max2(a,b) 13 # # 第二步:比较res1,c得到res2 14 # res2=max2(res1,c) 15 # # 第三步:比较res2,d得到res3 16 # res3=max2(res2,d) 17 # return res3 18 # 19 # res=max4(1,2,3,4) 20 # print(res) 21 22 23 # 2、函数的嵌套定义:在函数内定义其他函数 24 # def f1(): 25 # def f2(): 26 # pass 27 28 29 # 圆形 30 # 求圆形的求周长:2*pi*radius 31 def circle(radius,action=0): 32 from math import pi 33 34 def perimiter(radius): 35 return 2*pi*radius 36 37 # 求圆形的求面积:pi*(radius**2) 38 def area(radius): 39 return pi*(radius**2) 40 41 if action == 0: 42 return 2*pi*radius 43 44 elif action == 1: 45 return area(radius) 46 47 circle(33,action=0)
1 # 一:大前提: 2 # 闭包函数=名称空间与作用域+函数嵌套+函数对象 3 # 核心点:名字的查找关系是以函数定义阶段为准 4 5 # 二:什么是闭包函数 6 # "闭"函数指的该函数是内嵌函数 7 # "包"函数指的该函数包含对外层函数作用域名字的引用(不是对全局作用域) 8 9 # 闭包函数:名称空间与作用域的应用+函数嵌套 10 # def f1(): 11 # x = 33333333333333333333 12 # def f2(): 13 # print(x) 14 # f2() 15 # 16 # 17 # x=11111 18 # def bar(): 19 # x=444444 20 # f1() 21 # 22 # def foo(): 23 # x=2222 24 # bar() 25 # 26 # foo() 27 28 29 30 # 闭包函数:函数对象 31 # def f1(): 32 # x = 33333333333333333333 33 # def f2(): 34 # print('函数f2:',x) 35 # return f2 36 # 37 # f=f1() 38 # # print(f) 39 # 40 # # x=4444 41 # # f() 42 # def foo(): 43 # x=5555 44 # f() 45 # 46 # foo() 47 48 49 # 三:为何要有闭包函数=》闭包函数的应用 50 # 两种为函数体传参的方式 51 # 方式一:直接把函数体需要的参数定义成形参 52 # def f2(x): 53 # print(x) 54 # 55 # f2(1) 56 # f2(2) 57 # f2(3) 58 59 # 方式二: 60 # def f1(x): # x=3 61 # x=3 62 # def f2(): 63 # print(x) 64 # return f2 65 # 66 # x=f1(3) 67 # print(x) 68 # 69 # x() 70 71 72 73 import requests 74 75 # 传参的方案一: 76 # def get(url): 77 # response=requests.get(url) 78 # print(len(response.text)) 79 # 80 # get('https://www.baidu.com') 81 # get('https://www.cnblogs.com/linhaifeng') 82 # get('https://zhuanlan.zhihu.com/p/109056932') 83 84 85 # 传参的方案二: 86 def outter(url): 87 # url='https://www.baidu.com' 88 def get(): 89 response=requests.get(url) 90 print(len(response.text)) 91 return get 92 93 baidu=outter('https://www.baidu.com') 94 baidu() 95 96 cnblogs=outter('https://www.cnblogs.com/linhaifeng') 97 cnblogs() 98 99 zhihu=outter('https://zhuanlan.zhihu.com/p/109056932') 100 zhihu()
- 3 装饰器
1 # 一:储备知识 2 #1、 *args, **kwargs 3 # def index(x,y): 4 # print(x,y) 5 # 6 # 7 # def wrapper(*args,**kwargs): 8 # index(*args,**kwargs) # 9 # # index(y=222,x=111) 10 # wrapper(y=222,x=111) 11 12 13 # 2、名称空间与作用域:名称空间的的"嵌套"关系是在函数定义阶段,即检测语法的时候确定的 14 15 # 3、函数对象: 16 # 可以把函数当做参数传入 17 # 可以把函数当做返回值返回 18 # def index(): 19 # return 123 20 # 21 # def foo(func): 22 # return func 23 # 24 # foo(index) 25 26 # 4、函数的嵌套定义: 27 # def outter(func): 28 # def wrapper(): 29 # pass 30 # return wrapper 31 32 33 # 闭包函数 34 # def outter(): 35 # x=111 36 # def wrapper(): 37 # x 38 # return wrapper 39 # 40 # f=outter() 41 42 43 44 # 传参的方式一:通过参数的形式为函数体传值 45 46 47 # def wrapper(x): 48 # print(1) 49 # print(2) 50 # print(3) 51 # x 52 # 53 # wrapper(1) 54 # wrapper(2) 55 # wrapper(3) 56 # 传参的方式二:通过闭包的方式为函数体传值 57 # def outter(x): 58 # # x=1 59 # def wrapper(): 60 # print(1) 61 # print(2) 62 # print(3) 63 # x 64 # return wrapper # return outter内的wrapper那个函数的内地址 65 # 66 # # f1=outter(1) 67 # # f2=outter(2) 68 # # f3=outter(3) 69 # 70 # 71 # wrapper=outter(1) 72 #
1 """ 2 1、什么是装饰器 3 器指的是工具,可以定义成成函数 4 装饰指的是为其他事物添加额外的东西点缀 5 6 合到一起的解释: 7 装饰器指的定义一个函数,该函数是用来为其他函数添加额外的功能 8 9 10 2、为何要用装饰器 11 开放封闭原则 12 开放:指的是对拓展功能是开放的 13 封闭:指的是对修改源代码是封闭的 14 15 装饰器就是在不修改被装饰器对象源代码以及调用方式的前提下为被装饰对象添加新功能 16 3、如何用 17 """ 18 # 需求:在不修改index函数的源代码以及调用方式的前提下为其添加统计运行时间的功能 19 # def index(x,y): 20 # time.sleep(3) 21 # print('index %s %s' %(x,y)) 22 # 23 # index(111,222) 24 # # index(y=111,x=222) 25 # # index(111,y=222) 26 27 # 解决方案一:失败 28 # 问题:没有修改被装饰对象的调用方式,但是修改了其源代码 29 # import time 30 # 31 # def index(x,y): 32 # start=time.time() 33 # time.sleep(3) 34 # print('index %s %s' %(x,y)) 35 # stop = time.time() 36 # print(stop - start) 37 # 38 # index(111,222) 39 40 41 # 解决方案二:失败 42 # 问题:没有修改被装饰对象的调用方式,也没有修改了其源代码,并且加上了新功能 43 # 但是代码冗余 44 # import time 45 # 46 # def index(x,y): 47 # time.sleep(3) 48 # print('index %s %s' %(x,y)) 49 # 50 # start=time.time() 51 # index(111,222) 52 # stop=time.time() 53 # print(stop - start) 54 # 55 # 56 # 57 # start=time.time() 58 # index(111,222) 59 # stop=time.time() 60 # print(stop - start) 61 # 62 # 63 # start=time.time() 64 # index(111,222) 65 # stop=time.time() 66 # print(stop - start) 67 68 69 # 解决方案三:失败 70 # 问题:解决了方案二代码冗余问题,但带来一个新问题即函数的调用方式改变了 71 # import time 72 # 73 # def index(x,y): 74 # time.sleep(3) 75 # print('index %s %s' %(x,y)) 76 # 77 # def wrapper(): 78 # start=time.time() 79 # index(111,222) 80 # stop=time.time() 81 # print(stop - start) 82 # 83 # wrapper() 84 85 # 方案三的优化一:将index的参数写活了 86 # import time 87 # 88 # def index(x,y,z): 89 # time.sleep(3) 90 # print('index %s %s %s' %(x,y,z)) 91 # 92 # def wrapper(*args,**kwargs): 93 # start=time.time() 94 # index(*args,**kwargs) # index(3333,z=5555,y=44444) 95 # stop=time.time() 96 # print(stop - start) 97 # 98 # # wrapper(3333,4444,5555) 99 # # wrapper(3333,z=5555,y=44444) 100 101 102 # 方案三的优化二:在优化一的基础上把被装饰对象写活了,原来只能装饰index 103 # import time 104 # 105 # def index(x,y,z): 106 # time.sleep(3) 107 # print('index %s %s %s' %(x,y,z)) 108 # 109 # def home(name): 110 # time.sleep(2) 111 # print('welcome %s to home page' %name) 112 # 113 # 114 # def outter(func): 115 # # func = index的内存地址 116 # def wrapper(*args,**kwargs): 117 # start=time.time() 118 # func(*args,**kwargs) # index的内存地址() 119 # stop=time.time() 120 # print(stop - start) 121 # return wrapper 122 # 123 # index=outter(index) # index=wrapper的内存地址 124 # home=outter(home) # home=wrapper的内存地址 125 # 126 # 127 # home('egon') 128 # # home(name='egon') 129 130 # 方案三的优化三:将wrapper做的跟被装饰对象一模一样,以假乱真 131 # import time 132 # 133 # def index(x,y,z): 134 # time.sleep(3) 135 # print('index %s %s %s' %(x,y,z)) 136 # 137 # def home(name): 138 # time.sleep(2) 139 # print('welcome %s to home page' %name) 140 # 141 # def outter(func): 142 # def wrapper(*args,**kwargs): 143 # start=time.time() 144 # res=func(*args,**kwargs) 145 # stop=time.time() 146 # print(stop - start) 147 # return res 148 # 149 # 150 # 151 # return wrapper 152 # # 偷梁换柱:home这个名字指向的wrapper函数的内存地址 153 # home=outter(home) 154 # 155 # 156 # res=home('egon') # res=wrapper('egon') 157 # print('返回值--》',res) 158 159 # 大方向:如何在方案三的基础上不改变函数的调用方式 160 161 162 163 164 # 语法糖:让你开心的语法 165 import time 166 167 # 装饰器 168 # def timmer(func): 169 # def wrapper(*args,**kwargs): 170 # start=time.time() 171 # res=func(*args,**kwargs) 172 # stop=time.time() 173 # print(stop - start) 174 # return res 175 # 176 # 177 # 178 # return wrapper 179 # 180 # 181 # # 在被装饰对象正上方的单独一行写@装饰器名字 182 # # @timmer # index=timmer(index) 183 # def index(x,y,z): 184 # time.sleep(3) 185 # print('index %s %s %s' %(x,y,z)) 186 # 187 # # @timmer # home=timmer(ome) 188 # def home(name): 189 # time.sleep(2) 190 # print('welcome %s to home page' %name) 191 # 192 # 193 # index(x=1,y=2,z=3) 194 # home('egon') 195 196 197 198 # 思考题(选做),叠加多个装饰器,加载顺序与运行顺序 199 # @deco1 # index=deco1(deco2.wrapper的内存地址) 200 # @deco2 # deco2.wrapper的内存地址=deco2(deco3.wrapper的内存地址) 201 # @deco3 # deco3.wrapper的内存地址=deco3(index) 202 # def index(): 203 # pass 204 205 206 207 # 总结无参装饰器模板 208 # def outter(func): 209 # def wrapper(*args,**kwargs): 210 # # 1、调用原函数 211 # # 2、为其增加新功能 212 # res=func(*args,**kwargs) 213 # return res 214 # return wrapper 215 216 217 218 219 220 221 222 223 def auth(func): 224 def wrapper(*args,**kwargs): 225 # 1、调用原函数 226 # 2、为其增加新功能 227 name=input('your name>>: ').strip() 228 pwd=input('your password>>: ').strip() 229 if name == 'egon' and pwd == '123': 230 res=func(*args,**kwargs) 231 return res 232 else: 233 print('账号密码错误') 234 return wrapper 235 236 237 238 @auth 239 def index(): 240 print('from index') 241 242 index()
1 # 一、叠加多个装饰器的加载、运行分析(了解***) 2 3 def deco1(func1): # func1 = wrapper2的内存地址 4 def wrapper1(*args,**kwargs): 5 print('正在运行===>deco1.wrapper1') 6 res1=func1(*args,**kwargs) 7 return res1 8 return wrapper1 9 10 def deco2(func2): # func2 = wrapper3的内存地址 11 def wrapper2(*args,**kwargs): 12 print('正在运行===>deco2.wrapper2') 13 res2=func2(*args,**kwargs) 14 return res2 15 return wrapper2 16 17 def deco3(x): 18 def outter3(func3): # func3=被装饰对象index函数的内存地址 19 def wrapper3(*args,**kwargs): 20 print('正在运行===>deco3.outter3.wrapper3') 21 res3=func3(*args,**kwargs) 22 return res3 23 return wrapper3 24 return outter3 25 26 27 # 加载顺序自下而上(了解) 28 @deco1 # index=deco1(wrapper2的内存地址) ===> index=wrapper1的内存地址 29 @deco2 # index=deco2(wrapper3的内存地址) ===> index=wrapper2的内存地址 30 @deco3(111) # ===>@outter3===> index=outter3(index) ===> index=wrapper3的内存地址 31 def index(x,y): 32 print('from index %s:%s' %(x,y)) 33 34 # 执行顺序自上而下的,即wraper1-》wrapper2-》wrapper3 35 index(1,2) # wrapper1(1,2)
1 #偷梁换柱,即将原函数名指向的内存地址偷梁换柱成wrapper函数 2 # 所以应该将wrapper做的跟原函数一样才行 3 from functools import wraps 4 5 def outter(func): 6 @wraps(func) 7 def wrapper(*args, **kwargs): 8 """这个是主页功能""" 9 res = func(*args, **kwargs) # res=index(1,2) 10 return res 11 12 # 手动将原函数的属性赋值给wrapper函数 13 # 1、函数wrapper.__name__ = 原函数.__name__ 14 # 2、函数wrapper.__doc__ = 原函数.__doc__ 15 # wrapper.__name__ = func.__name__ 16 # wrapper.__doc__ = func.__doc__ 17 18 return wrapper 19 20 21 22 @outter # index=outter(index) 23 def index(x,y): 24 """这个是主页功能""" 25 print(x,y) 26 27 28 print(index.__name__) 29 print(index.__doc__) #help(index)
1 # 一:知识储备 2 # 由于语法糖@的限制,outter函数只能有一个参数,并且该才是只用来接收 3 # 被装饰对象的内存地址 4 # def outter(func): 5 # # func = 函数的内存地址 6 # def wrapper(*args,**kwargs): 7 # res=func(*args,**kwargs) 8 # return res 9 # return wrapper 10 # 11 # # @outter # index=outter(index) # index=>wrapper 12 # @outter # outter(index) 13 # def index(x,y): 14 # print(x,y) 15 16 # 偷梁换柱之后 17 # index的参数什么样子,wrapper的参数就应该什么样子 18 # index的返回值什么样子,wrapper的返回值就应该什么样子 19 # index的属性什么样子,wrapper的属性就应该什么样子==》from functools import wraps 20 21 22 # 山炮玩法: 23 # def auth(func,db_type): 24 # def wrapper(*args, **kwargs): 25 # name=input('your name>>>: ').strip() 26 # pwd=input('your password>>>: ').strip() 27 # 28 # if db_type == 'file': 29 # print('基于文件的验证') 30 # if name == 'egon' and pwd == '123': 31 # res = func(*args, **kwargs) 32 # return res 33 # else: 34 # print('user or password error') 35 # elif db_type == 'mysql': 36 # print('基于mysql的验证') 37 # elif db_type == 'ldap': 38 # print('基于ldap的验证') 39 # else: 40 # print('不支持该db_type') 41 # 42 # return wrapper 43 # 44 # # @auth # 账号密码的来源是文件 45 # def index(x,y): 46 # print('index->>%s:%s' %(x,y)) 47 # 48 # # @auth # 账号密码的来源是数据库 49 # def home(name): 50 # print('home->>%s' %name) 51 # 52 # # @auth # 账号密码的来源是ldap 53 # def transfer(): 54 # print('transfer') 55 # 56 # 57 # index=auth(index,'file') 58 # home=auth(home,'mysql') 59 # transfer=auth(transfer,'ldap') 60 # 61 # # index(1,2) 62 # # home('egon') 63 # # transfer() 64 65 66 # 山炮二 67 # def auth(db_type): 68 # def deco(func): 69 # def wrapper(*args, **kwargs): 70 # name=input('your name>>>: ').strip() 71 # pwd=input('your password>>>: ').strip() 72 # 73 # if db_type == 'file': 74 # print('基于文件的验证') 75 # if name == 'egon' and pwd == '123': 76 # res = func(*args, **kwargs) 77 # return res 78 # else: 79 # print('user or password error') 80 # elif db_type == 'mysql': 81 # print('基于mysql的验证') 82 # elif db_type == 'ldap': 83 # print('基于ldap的验证') 84 # else: 85 # print('不支持该db_type') 86 # 87 # return wrapper 88 # return deco 89 # 90 # deco=auth(db_type='file') 91 # @deco # 账号密码的来源是文件 92 # def index(x,y): 93 # print('index->>%s:%s' %(x,y)) 94 # 95 # deco=auth(db_type='mysql') 96 # @deco # 账号密码的来源是数据库 97 # def home(name): 98 # print('home->>%s' %name) 99 # 100 # deco=auth(db_type='ldap') 101 # @deco # 账号密码的来源是ldap 102 # def transfer(): 103 # print('transfer') 104 # 105 # 106 # index(1,2) 107 # home('egon') 108 # transfer() 109 110 111 # 语法糖 112 def auth(db_type): 113 def deco(func): 114 def wrapper(*args, **kwargs): 115 name = input('your name>>>: ').strip() 116 pwd = input('your password>>>: ').strip() 117 118 if db_type == 'file': 119 print('基于文件的验证') 120 if name == 'egon' and pwd == '123': 121 res = func(*args, **kwargs) # index(1,2) 122 return res 123 else: 124 print('user or password error') 125 elif db_type == 'mysql': 126 print('基于mysql的验证') 127 elif db_type == 'ldap': 128 print('基于ldap的验证') 129 else: 130 print('不支持该db_type') 131 return wrapper 132 return deco 133 134 135 @auth(db_type='file') # @deco # index=deco(index) # index=wrapper 136 def index(x, y): 137 print('index->>%s:%s' % (x, y)) 138 139 @auth(db_type='mysql') # @deco # home=deco(home) # home=wrapper 140 def home(name): 141 print('home->>%s' % name) 142 143 144 @auth(db_type='ldap') # 账号密码的来源是ldap 145 def transfer(): 146 print('transfer') 147 148 # index(1, 2) 149 # home('egon') 150 # transfer() 151 152 153 154 155 # 有参装饰器模板 156 def 有参装饰器(x,y,z): 157 def outter(func): 158 def wrapper(*args, **kwargs): 159 res = func(*args, **kwargs) 160 return res 161 return wrapper 162 return outter 163 164 @有参装饰器(1,y=2,z=3) 165 def 被装饰对象(): 166 pass
- 4 迭代器&生成器
1 ''' 2 1、什么是迭代器 3 迭代器指的是迭代取值的工具,迭代是一个重复的过程,每次重复 4 都是基于上一次的结果而继续的,单纯的重复并不是迭代 5 6 2、为何要有迭代器 7 迭代器是用来迭代取值的工具,而涉及到把多个值循环取出来的类型 8 有:列表、字符串、元组、字典、集合、打开文件 9 10 l=['egon','liu','alex'] 11 i=0 12 while i < len(l): 13 print(l[i]) 14 i+=1 15 16 上述迭代取值的方式只适用于有索引的数据类型:列表、字符串、元组 17 为了解决基于索引迭代器取值的局限性 18 python必须提供一种能够不依赖于索引的取值方式,这就是迭代器 19 20 21 3、如何用迭代器 22 23 ''' 24 # 1、可迭代的对象:但凡内置有__iter__方法的都称之为可迭代的对象 25 # s1='' 26 # # s1.__iter__() 27 # 28 # l=[] 29 # # l.__iter__() 30 # 31 # t=(1,) 32 # # t.__iter__() 33 # 34 # d={'a':1} 35 # # d.__iter__() 36 # 37 # set1={1,2,3} 38 # # set1.__iter__() 39 # 40 # with open('a.txt',mode='w') as f: 41 # # f.__iter__() 42 # pass 43 44 # 2、调用可迭代对象下的__iter__方法会将其转换成迭代器对象 45 d={'a':1,'b':2,'c':3} 46 d_iterator=d.__iter__() 47 # print(d_iterator) 48 49 # print(d_iterator.__next__()) 50 # print(d_iterator.__next__()) 51 # print(d_iterator.__next__()) 52 # print(d_iterator.__next__()) # 抛出异常StopIteration 53 54 55 # while True: 56 # try: 57 # print(d_iterator.__next__()) 58 # except StopIteration: 59 # break 60 # 61 # print('====>>>>>>') # 在一个迭代器取值取干净的情况下,再对其取值娶不到 62 # d_iterator=d.__iter__() 63 # while True: 64 # try: 65 # print(d_iterator.__next__()) 66 # except StopIteration: 67 # break 68 69 70 # l=[1,2,3,4,5] 71 # l_iterator=l.__iter__() 72 # 73 # while True: 74 # try: 75 # print(l_iterator.__next__()) 76 # except StopIteration: 77 # break 78 79 80 # 3、可迭代对象与迭代器对象详解 81 # 3.1 可迭代对象("可以转换成迭代器的对象"):内置有__iter__方法对象 82 # 可迭代对象.__iter__(): 得到迭代器对象 83 84 # 3.2 迭代器对象:内置有__next__方法并且内置有__iter__方法的对象 85 # 迭代器对象.__next__():得到迭代器的下一个值 86 # 迭代器对象.__iter__():得到迭代器的本身,说白了调了跟没调一个样子 87 # dic={'a':1,'b':2,'c':3} 88 # 89 # dic_iterator=dic.__iter__() 90 # print(dic_iterator is dic_iterator.__iter__().__iter__().__iter__()) 91 # 92 93 # 4、可迭代对象:字符串、列表、元组、字典、集合、文件对象 94 # 迭代器对象:文件对象 95 # s1='' 96 # s1.__iter__() 97 # 98 # l=[] 99 # l.__iter__() 100 # 101 # t=(1,) 102 # t.__iter__() 103 # 104 # 105 # d={'a':1} 106 # d.__iter__() 107 # 108 # set1={1,2,3} 109 # set1.__iter__() 110 # 111 # 112 # with open('a.txt',mode='w') as f: 113 # f.__iter__() 114 # f.__next__() 115 116 117 118 119 120 # 5、for循环的工作原理:for循环可以称之为叫迭代器循环 121 d={'a':1,'b':2,'c':3} 122 123 # 1、d.__iter__()得到一个迭代器对象 124 # 2、迭代器对象.__next__()拿到一个返回值,然后将该返回值赋值给k 125 # 3、循环往复步骤2,直到抛出StopIteration异常for循环会捕捉异常然后结束循环 126 # for k in d: 127 # print(k) 128 129 130 # with open('a.txt',mode='rt',encoding='utf-8') as f: 131 # for line in f: # f.__iter__() 132 # print(line) 133 134 135 # list('hello') #原理同for循环 136 137 # 6、迭代器优缺点总结 138 # 6.1 缺点: 139 # I、为序列和非序列类型提供了一种统一的迭代取值方式。 140 # II、惰性计算:迭代器对象表示的是一个数据流,可以只在需要时才去调用next来计算出一个值,就迭代器本身来说,同一时刻在内存中只有一个值,因而可以存放无限大的数据流,而对于其他容器类型,如列表,需要把所有的元素都存放于内存中,受内存大小的限制,可以存放的值的个数是有限的。 141 142 # 6.2 缺点: 143 # I、除非取尽,否则无法获取迭代器的长度 144 # 145 # II、只能取下一个值,不能回到开始,更像是‘一次性的’,迭代器产生后的唯一目标就是重复执行next方法直到值取尽,否则就会停留在某个位置,等待下一次调用next;若是要再次迭代同个对象,你只能重新调用iter方法去创建一个新的迭代器对象,如果有两个或者多个循环使用同一个迭代器,必然只会有一个循环能取到值。
1 # 如何得到自定义的迭代器: 2 # 在函数内一旦存在yield关键字,调用函数并不会执行函数体代码 3 # 会返回一个生成器对象,生成器即自定义的迭代器 4 def func(): 5 print('第一次') 6 yield 1 7 print('第二次') 8 yield 2 9 print('第三次') 10 yield 3 11 print('第四次') 12 13 14 # g=func() 15 # print(g) 16 # 生成器就是迭代器 17 # g.__iter__() 18 # g.__next__() 19 20 21 # 会触发函数体代码的运行,然后遇到yield停下来,将yield后的值 22 # 当做本次调用的结果返回 23 # res1=g.__next__() 24 # print(res1) 25 # 26 # 27 # res2=g.__next__() 28 # print(res2) 29 # 30 # res3=g.__next__() 31 # print(res3) 32 # 33 # res4=g.__next__() 34 35 36 37 # len('aaa') # 'aaa'.__len__() 38 39 # next(g) # g.__next__() 40 # iter(可迭代对象) # 可迭代对象.__iter__() 41 42 43 # 应用案列 44 def my_range(start,stop,step=1): 45 # print('start...') 46 while start < stop: 47 yield start 48 start+=step 49 # print('end....') 50 51 52 # g=my_range(1,5,2) # 1 3 53 # print(next(g)) 54 # print(next(g)) 55 # print(next(g)) 56 57 for n in my_range(1,7,2): 58 print(n) 59 60 61 # 总结yield: 62 # 有了yield关键字,我们就有了一种自定义迭代器的实现方式。yield可以用于返回值,但不同于return,函数一旦遇到return就结束了,而yield可以保存函数的运行状态挂起函数,用来返回多次值
1 # x=yield 返回值 2 3 # 一: 4 # def dog(name): 5 # print('道哥%s准备吃东西啦...' %name) 6 # while True: 7 # # x拿到的是yield接收到的值 8 # x = yield # x = '肉包子' 9 # print('道哥%s吃了 %s' %(name,x)) 10 # 11 # 12 # g=dog('alex') 13 # g.send(None) # 等同于next(g) 14 # 15 # g.send(['一根骨头','aaa']) 16 # # g.send('肉包子') 17 # # g.send('一同泔水') 18 # # g.close() 19 # # g.send('1111') # 关闭之后无法传值 20 21 22 # 二: 23 def dog(name): 24 food_list=[] 25 print('道哥%s准备吃东西啦...' %name) 26 while True: 27 # x拿到的是yield接收到的值 28 x = yield food_list # x = '肉包子' 29 print('道哥%s吃了 %s' %(name,x)) 30 food_list.append(x) # ['一根骨头','肉包子'] 31 # 32 # g=dog('alex') 33 # res=g.send(None) # next(g) 34 # print(res) 35 # 36 # res=g.send('一根骨头') 37 # print(res) 38 # 39 # res=g.send('肉包子') 40 # print(res) 41 # # g.send('一同泔水') 42 43 44 45 46 def func(): 47 print('start.....') 48 x=yield 1111 # x='xxxxx' 49 print('哈哈哈啊哈') 50 print('哈哈哈啊哈') 51 print('哈哈哈啊哈') 52 print('哈哈哈啊哈') 53 yield 22222 54 55 g=func() 56 res=next(g) 57 print(res) 58 59 res=g.send('xxxxx') 60 print(res)
- 5 三元表达式&列表生成式&递归
1 # 针对以下需求 2 # def func(x,y): 3 # if x > y: 4 # return x 5 # else: 6 # return y 7 # 8 # res=func(1,2) 9 # print(res) 10 11 # 三元表达式 12 # 语法格式: 条件成立时要返回的值 if 条件 else 条件不成立时要返回的值 13 x=1 14 y=2 15 16 # res=x if x > y else y 17 # print(res) 18 19 20 res=111111 if 'egon' == 'egon' else 2222222222 21 print(res) 22 23 24 25 # 应用举例 26 def func(): 27 # if 1 > 3: 28 # x=1 29 # else: 30 # x=3 31 32 x = 1 if 1 > 3 else 3
1 # 1、列表生成式 2 l = ['alex_dsb', 'lxx_dsb', 'wxx_dsb', "xxq_dsb", 'egon'] 3 # new_l=[] 4 # for name in l: 5 # if name.endswith('dsb'): 6 # new_l.append(name) 7 8 9 # new_l=[name for name in l if name.endswith('dsb')] 10 # new_l=[name for name in l] 11 12 # print(new_l) 13 14 # 把所有小写字母全变成大写 15 # new_l=[name.upper() for name in l] 16 # print(new_l) 17 18 # 把所有的名字去掉后缀_dsb 19 # new_l=[name.replace('_dsb','') for name in l] 20 # print(new_l) 21 22 # 2、字典生成式 23 # keys=['name','age','gender'] 24 # dic={key:None for key in keys} 25 # print(dic) 26 27 # items=[('name','egon'),('age',18),('gender','male')] 28 # res={k:v for k,v in items if k != 'gender'} 29 # print(res) 30 31 # 3、集合生成式 32 # keys=['name','age','gender'] 33 # set1={key for key in keys} 34 # print(set1,type(set1)) 35 36 37 # 4、生成器表达式 38 # g=(i for i in range(10) if i > 3) 39 # !!!!!!!!!!!强调!!!!!!!!!!!!!!! 40 # 此刻g内部一个值也没有 41 42 # print(g,type(g)) 43 44 # print(g) 45 # print(next(g)) 46 # print(next(g)) 47 # print(next(g)) 48 # print(next(g)) 49 # print(next(g)) 50 # print(next(g)) 51 # print(next(g)) 52 53 54 with open('笔记.txt', mode='rt', encoding='utf-8') as f: 55 # 方式一: 56 # res=0 57 # for line in f: 58 # res+=len(line) 59 # print(res) 60 61 # 方式二: 62 # res=sum([len(line) for line in f]) 63 # print(res) 64 65 # 方式三 :效率最高 66 # res = sum((len(line) for line in f)) 67 # 上述可以简写为如下形式 68 res = sum(len(line) for line in f) 69 print(res)
1 # 一:递归的定义 2 # 函数的递归调用:是函数嵌套调用的一种特殊形式 3 # 具体是指: 4 # 在调用一个函数的过程中又直接或者间接地调用到本身 5 6 # 直接调用本身 7 # def f1(): 8 # print('是我是我还是我') 9 # f1() 10 # f1() 11 12 # 间接接调用本身 13 # def f1(): 14 # print('===>f1') 15 # f2() 16 # 17 # def f2(): 18 # print('===>f2') 19 # f1() 20 # 21 # f1() 22 23 24 # 一段代码的循环运行的方案有两种 25 # 方式一:while、for循环 26 # while True: 27 # print(1111) 28 # print(2222) 29 # print(3333) 30 31 # 方式二:递归的本质就是循环: 32 # def f1(): 33 # print(1111) 34 # print(2222) 35 # print(3333) 36 # f1() 37 # f1() 38 39 40 # 二:需要强调的的一点是: 41 # 递归调用不应该无限地调用下去,必须在满足某种条件下结束递归调用 42 # n=0 43 # while n < 10: 44 # print(n) 45 # n+=1 46 47 48 # def f1(n): 49 # if n == 10: 50 # return 51 # print(n) 52 # n+=1 53 # f1(n) 54 # 55 # f1(0) 56 57 # 三:递归的两个阶段 58 # 回溯:一层一层调用下去 59 # 递推:满足某种结束条件,结束递归调用,然后一层一层返回 60 61 # age(5) = age(4) + 10 62 # age(4) = age(3) + 10 63 # age(3) = age(2) + 10 64 # age(2) = age(1) + 10 65 # age(1) = 18 66 67 # def age(n): 68 # if n == 1: 69 # return 18 70 # return age(n-1) + 10 71 # 72 # 73 # res=age(5) 74 # print(res) 75 76 # 四:递归的应用 77 l=[1,2,[3,[4,[5,[6,[7,[8,[9,10,11,[12,[13,]]]]]]]]]] 78 79 def f1(list1): 80 for x in list1: 81 if type(x) is list: 82 # 如果是列表,应该再循环、再判断,即重新运行本身的代码 83 f1(x) 84 else: 85 print(x) 86 87 f1(l)
- 6 二分法&匿名函数
1 # 算法:是高效解决问题的办法 2 # 算法之二分法 3 4 # 需求:有一个按照从小到大顺序排列的数字列表 5 # 需要从该数字列表中找到我们想要的那个一个数字 6 # 如何做更高效??? 7 8 9 nums=[-3,4,7,10,13,21,43,77,89] 10 find_num=10 11 12 nums=[-3,4,13,10,-2,7,89] 13 nums.sort() 14 print(nums) 15 16 # 方案一:整体遍历效率太低 17 # for num in nums: 18 # if num == find_num: 19 # print('find it') 20 # break 21 22 # 方案二:二分法 23 # def binary_search(find_num,列表): 24 # mid_val=找列表中间的值 25 # if find_num > mid_val: 26 # # 接下来的查找应该是在列表的右半部分 27 # 列表=列表切片右半部分 28 # binary_search(find_num,列表) 29 # elif find_num < mid_val: 30 # # 接下来的查找应该是在列表的左半部分 31 # 列表=列表切片左半部分 32 # binary_search(find_num,列表) 33 # else: 34 # print('find it') 35 36 # nums=[-3,4,7,10,13,21,43,77,89] 37 # find_num=8 38 # def binary_search(find_num,l): 39 # print(l) 40 # if len(l) == 0: 41 # print('找的值不存在') 42 # return 43 # mid_index=len(l) // 2 44 # 45 # if find_num > l[mid_index]: 46 # # 接下来的查找应该是在列表的右半部分 47 # l=l[mid_index+1:] 48 # binary_search(find_num,l) 49 # elif find_num < l[mid_index]: 50 # # 接下来的查找应该是在列表的左半部分 51 # l=l[:mid_index] 52 # binary_search(find_num,l) 53 # else: 54 # print('find it') 55 # 56 # binary_search(find_num,nums)
1 # 1、def用于定义有名函数 2 # func=函数的内存地址 3 # def func(x,y): 4 # return x+y 5 6 # print(func) 7 # 2、lamdab用于定义匿名函数 8 # print(lambda x,y:x+y) 9 10 11 # 3、调用匿名函数 12 # 方式一: 13 # res=(lambda x,y:x+y)(1,2) 14 # print(res) 15 16 # 方式二: 17 # func=lambda x,y:x+y 18 # res=func(1,2) 19 # print(res) 20 21 #4、匿名用于临时调用一次的场景:更多的是将匿名与其他函数配合使用
1 salaries={ 2 'siry':3000, 3 'tom':7000, 4 'lili':10000, 5 'jack':2000 6 } 7 # 需求1:找出薪资最高的那个人=》lili 8 # res=max([3,200,11,300,399]) 9 # print(res) 10 11 # res=max(salaries) 12 # print(res) 13 14 15 salaries={ 16 'siry':3000, 17 'tom':7000, 18 'lili':10000, 19 'jack':2000 20 } 21 # 迭代出的内容 比较的值 22 # 'siry' 3000 23 # 'tom' 7000 24 # 'lili' 10000 25 # 'jack' 2000 26 27 # def func(k): 28 # return salaries[k] 29 30 # ========================max的应用 31 # res=max(salaries,key=func) # 返回值=func('siry') 32 # print(res) 33 34 # res=max(salaries,key=lambda k:salaries[k]) 35 # print(res) 36 37 # ========================min的应用 38 # res=min(salaries,key=lambda k:salaries[k]) 39 # print(res) 40 41 42 # ========================sorted排序 43 # salaries={ 44 # 'siry':3000, 45 # 'tom':7000, 46 # 'lili':10000, 47 # 'jack':2000 48 # } 49 res=sorted(salaries,key=lambda k:salaries[k],reverse=True) 50 # print(res) 51 52 # ========================map的应用(了解) 53 # l=['alex','lxx','wxx','薛贤妻'] 54 # new_l=(name+'_dsb' for name in l) 55 # print(new_l) 56 57 # res=map(lambda name:name+'_dsb',l) 58 # print(res) # 生成器 59 # ========================filter的应用(了解) 60 # l=['alex_sb','lxx_sb','wxx','薛贤妻'] 61 # res=(name for name in l if name.endswith('sb')) 62 # print(res) 63 64 # res=filter(lambda name:name.endswith('sb'),l) 65 # print(res) 66 67 # ========================reduce的应用(了解) 68 from functools import reduce 69 res=reduce(lambda x,y:x+y,[1,2,3],10) # 16 70 print(res) 71 72 res=reduce(lambda x,y:x+y,['a','b','c']) # 'a','b' 73 print(res)