第五章 函数
v = 前面的值 if 条件 else 后面 条件为真 v=前面的值,条件为假v=后面的值 if 条件: v = '前面' else: v = '后面'
例题: 让用户输入值,如果值是整数,则转换成整数,否则赋值为none data = input('') value = int(data) True if datea.isdecimal() else none
为了增加代码的重复利用,可读性,所以引入函数
面向过程编程 user_input = input('请输入角色:') if user_input == '管理员': pass #给管理员发邮件,10行代码 if user_input == '业务员': pas s#给业务员发邮件,10行代码 if user_input == '老板': pass #给老板发邮件,10行代码
-
本质:将N行代码拿到别处并给它起个名字,以后通过名字可以找到这段代码并执行
-
场景:
-
代码重复执行
-
代码量特别多超过一屏,可以选择通过函数进行代码分分割
5.2.1函数的基本结构
#函数的定义 def 函数名(): 函数名的命名规则和变量名命名规则一样 函数内容 pass 函数的执行 函数名()
例题: def get_list_first_data(): v = [11,22,33,44] print(v[0]) get_list_first_data() ##注意:函数如果不被调用,则内部代码永远不会被执行
参数:
-
-
基本的参数:def func(a,b) pass
-
默认值:def func(a,b=123) pass (注意:默认值如果是不可变类型,随便玩;可变类型:有坑)
-
无敌:*args,**kwarges接受任意的位置参数和关键字参数
-
-
实参
-
位置传参
-
例题: #1.请写一个函数,函数计算列表info = [11,22,33,44,55]中所有元素的和 def get_sum(): info = [11,22,33,44,55] data = 0 for i in info: data =data +i print(data) get_sum() #2请写一个函数,函数计算列表中所有元素的和 def get_list_sum(a): #a是形参 data = 0 for item in a: data += item print(data) get_list_sum([11,22,33,44]) #列表是实参 get_list_sum([99,77,33,44]) # 3请写一个函数,函数将两个列表拼接起来 def join_list(a,b): result = [] result.extend(a) result.extend(b) print(result) join_list([11,22,33],[55,66,77]) #4 计算一个列表的长度 def my_len(arg): count = 0 for item in arg: count +=1 print(count) v = [11,22,334,] my_len(v) #5 发送邮件 def send_email(role,to): template = '要给%s%s发送邮件'%(role,to,) print(template) user_input = input('请输入角色:') if user_input == '管理员': send_email('管理员','管理员邮箱') if user_input == '业务员': send_email('业务员','业务员邮箱') if user_input == '老板': send_email('老板','老板邮箱')
def func(arg): #.... return 9 #返回值为9,默认:return None 返回值可以是列表、字典等 val = func('dedgggggg') def func(): return '完成' # 函数每次执行到此,就返回,不执行下面的代码 for i in range(10): print(i) func() v = func() print(v) #特殊:返回元组 def func(): for i in range(10): print(i) return '完成' func() #0
练习题
#1.让用户输入一个字符串,计算字符串中有多少个大写的A,有多少个A就在文件a.txt中写多少个’李奇‘ def get_char_count(data): sum_counter = 0 for i in data: if i =='A': sum_counter +=1 return sum_counter def write_file(line): if len(line) == 0: return False #函数执行过程中一旦遇到return,则停止执行 with open('a.txt',mode = 'w',encoding= 'utf-8')as f: f.write(line) return True content = input('请输入:') counter = get_char_count(content) write_data = '李奇'* counter status = write_file((write_data)) if status: print('写入成功') else: print('写入失败')
练习题: 1.写函数,计算一个列表中有多少个数字,打印:列表中有%s个数字 def list_number(data): total = 0 for item in data: if type(item) == int: total +=1 msg = '列表中有%s个数字'%(total,) print(msg) list_number([1,2,34,'alxe']) def list_number(data): total = 0 for item in data: if type(item) ==int: total +=1 return total v = list_number([1,2,3,'alxe',5,6]) msg = '列表中有%s个数字'%(v,) print(msg) #2写函数,计算一个列表中偶数索引位置的数据构成另外一个列表,并返回 def list_data(arg): v = arg[::2] return v data = list_data([1,2,3,4,5,6]) def list_data(arg): v = [] for i in range(0,len(arg)): if i % 2 == 0: v.append(i) return v data = list_data([1,3,4,5]) #利用参数,读取文件,将文件的内容构造成指定格式的数据,并返回 ''' a.txt文件 alex|123|18 eric|uiuf|19 目标结构 ['alex|123|18','eric|uiuf|19']并返回 [['alex','123',18],['eric','uiuf',19] [{'name':'alex','pwd':'123','age':18}, {'name':'eric','pwd':'uiuf','age':19}] def read_line(arg): with open('a.txt', mode='r', encoding='utf-8')as f: data = f.read() list = data.split('\n') print(list) line = read_line(1) def read_line(arg): with open('a.txt',mode='r',encoding='utf-8') as f: data = f.read() list = data.split('\n') now_list = [] now_list.append(list[0].split('|')) now_list.append(list[1].split('|')) print(now_list) line = read_line(1) ''' def read_line(arg): with open('a.txt',mode='r',encoding='utf-8') as f: data = f.read() list = data.split('\n') #[alex|123|18,eric|uiuf|19] now_list = [] now_list.append(list[0].split('|')) now_list.append(list[1].split('|')) #[alex,123,18],[eric,uiuf,19]] keys = ['name','pwd','age'] list2 = [] dic = {} for l in now_list: for i in range(len(l)): dic[keys[i]] = l[i] list2.append(dic) print(list2) line = read_line(1)
数据类型中的方法到底有没有返回值?
1.无返回值
v = [11,22,44] v.append(99)#无返回值
2.仅有返回值:内部没有修改
v = 'alex' result = v.split('l') v = {'k1':v1} result1 = v.get('k1') result2= v.keys()
3.有返回值+内部修改数据
v = [11,22,333]
result = v.pop()
4.常用需要记住
4.1 str
-
-
split ,有,返回列表
-
replace,返回字符串
-
upper 返回字符串
-
lower 返回字符串
-
-
-
insert 无
-
pop 返回要删除的数据
-
remove 无
-
-
-
keys有
-
values 有
-
def func(a1,a2,a3): print(a1,a2,a3) func(1,'asdf',True)
def func(a1,a2): print(a1,a2) func(1,2)
def func(a1,a2): print(a1,a2) func(a2=99,a1= 1) #关键字传参和位置传参可以混合使用,位置传入参数一定要在前面,关键字参数一定在后,总参数个数不变(先位置参数后关键字参数) def func(a1,a2,a3): print(a1,a2,a3) func(1,2,a3=9) #输出1 2 9 func(1,a2=2,a3=9) func(a1=1,a2=2,a3=9) func(a1=1,2,9)#错误
注意:关键字传参和位置传参可以混合使用,位置传入参数一定要在前面,关键字参数一定在后,总参数个数不变(先位置参数后关键字参数)
def func(a1,a2=9): #=表示可传可不传,不传参数时等于默认值 pass func函数可以接收两个参数,调用函数进行传值时: func(1,2) func(1,a2=10) func(a1=123,a2=999) func(1) def func(a1,a2,a3=4): print(a1,a2,a3) # func(11,22) #11 22 4 func(11,22,10) #11 22 10 def file_write(file_path,content='\n'): #flie_path是文件路径,content是写入的内容,content后面不写是默认换行 pass def file_read(file_path, num=1): ##flie_path是文件路径,num是读的第几行,写入1就是第一行 pass
def func(*args): #* 指的是可以接收多个参数,不确定函数接收多少个参数的时候用,不支持关键字传参,只支持位置传参 print(args) func(*(11,22,33,44,55)) #args=(11, 22, 33, 44, 55)将元素循环添加到元组 func(*[11,22,33,44])#列表也是一样
b:实参不带*
def func(*args): print(args) func((11, 22, 33, 44, 55)) args=((11, 22, 33, 44, 55),) ## 只能用位置参数
2.**kwargs(关键字参数):可以接收任意个数的关键字参数,并将参数转换成字典,只能用关键字传参
a:调用函数无**
def func(**kwargs): print(**kwargs) func(k1=1) #{'k1': 1} func(k1=1,k2='alex') #{'k1': 1, 'k2': 'alex'}
b:调用函数有**
def func(**kwargs): print(kwargs) func(k1=1) #kwargs={'k1': 1} func(**{'k1':'v1','k2':'v2'}) #kwargs={'k1': 'v1', 'k2': 'v2'} func(k1={'k1':999,'k2':777},k2='alex') #kwargs={'k1': {'k1': 999, 'k2': 777}, 'k2': 'alex'}
3.综合应用:无敌+无敌
def func(*args,**kwargs): print(args,kwargs) func(1,2,3,4,k1=2,k2=2,k4=999) #args=(1, 2, 3, 4) kwargs={'k1': 2, 'k2': 2, 'k4': 999} func(*(1,2,3,4),k1=2,k2=2,k4=999) #args=(1, 2, 3, 4) kwargs={'k1': 2, 'k2': 2, 'k4': 999} func(11,22,33,*(1,2,3),**{'k1':1,'k2':2}) #args=(11, 22, 33, 1, 2, 3) kwargs={'k1': 1, 'k2': 2} func(11,22,33,*(1,2,3),k11='alex',**{'k1':1,'k2':2})#args=(11, 22, 33, 1, 2, 3) kwargs={'k11': 'alex', 'k1': 1, 'k2': 2}
练习题:
def func(*args): #* 指的是可以接收多个参数,不确定函数接收多少个参数的时候用,一般*加args print(args) func(1) #args=(1,) func(1,2) #args=(1, 2) func(1,2,[11,22],123123,999,True,'alex') #args=(1, 2, [11, 22], 123123, 999, True, 'alex') func((11,22,33,44,55)) #args=((11, 22, 33, 44, 55),)#元组套元组 func(*(11,22,33,44,55)) #args=(11, 22, 33, 44, 55)#将元素循环添加到元组,打散 def func(a1,*args,a2): #args后面还有参数时,a2必须要用关键字传参 print(a1,args,a2) func(1,2,4,5,a2=9) #a1=1 args=(2, 4, 5),a2=9 def func(a1,*args,a2=9): #args后面还有参数时,a2必须要用关键字传参 print(a1,args,a2) func(1,2,4,5) #a1=1 args=(2, 4, 5),a2=9 def func(**kwargs): 位置传参 print(kwargs) func(k1=1) #{'k1': 1} func(k1=1,k2='alex') #{'k1': 1, 'k2': 'alex'}
def func(a1,a2): pass def func(a1,a2=None): pass def func(*args,**kwarge): pass
-
-
函数:局部作用域
-
nt(x1) print(a)#1 print(b) #2 b = 2 print(a)#1 s1()#666 print(x1)#报错 def s2(): print(a,b)#1,2 print(x1)#可以找到函数位置 s2() ''' a = 1 def s1(): x1 = 666 print(x1) print(a)#1 print(b)#2 def xxx(): pass b = 2 print(a)#1 s1()#666 print(x1)#报错 a=888 def s2(): print(a,b)#888,2 s1()#666 s2() # 888 2
def func(): x = 9 print(x) func()#9 def func(): x = 9
作用域中查找数据的规则:优先在自己的作用域查找数据,自己没有就去“父级”-->"父级“-->全局,全局没有就报错
全局变量必须大写,局部变量小写
例题:
##自己有 x =10 def func(): x = 9 print(x) func() #9 ##自己没有,父级有 x =10 def func(): print(x) func() #10 ##自己没有,全局也没有 def func(): print(x) func()#报错 def func(): x = 9 print(x)#9 def x1(): x =999 print(x) print(x) func()#9 ''' ''' x =10 def func(): x = 9 print(x)#9 def x1(): x =999 print(x) print(x)#9 x1()#999 func()#9 ''' x =10 def func(): x = 8 print(x)#8 def x1(): x =999 print(x) x1()#999 print(x) func()# 8 x =10 def func(): x = 8 print(x)#8 def x1(): print(x) x = 9 x1()#9 x = 11 print(x) func()#11 x =10 def func(): x = 8 print(x)#8 def x1(): print(x) x1() #8 x = 9 x1() #9 x = 10 print(x) func()#10
练习题:子作用域中只能找到父级中的值,默认无法重新为父级赋值(global/nonlocal可以强制做)
name = 'oldboy' def func(): name = 'alex' #在自己作用域再创建一个这样的值 print(name) #alex func() print(name) ##oldboy ######## name = [1,2,3,4] def func(): name .append(999) print(name)#[1, 2, 3, 4, 999] func() print(name) #[1, 2, 3, 4, 999] ##注意:因为字符串是不可变类型,而列表、元组等是可变类型所以可以用增加的方法 ####如果非要对全局的变量进行赋值可以用global进行重新修改 name = '老男孩' def func(): global name name = 'alex' func() print(name) #alex ######示例 name = '老男孩' def func(): name = 'alex' def inner(): global name name = 999 inner() print(name) #alex func() print(name) #999 ###nonlacal,找到父级的变量修改 name = '老男孩' def func(): name = 'alex' def inner(): nonlocal name #nonlocal 是指找到上一级的name修改 name = 999 inner() print(name) #999 func() print(name) #老男孩 ######示例 name = '老男孩' def func(): name = 'alex' def inner(): name = 999 def test(): global name name = '888' test() inner() print(name) #alex func() print(name) #888 ####示例 name = '老男孩' def func(): name = 'alex' def inner(): name = 999 def test(): nonlocal name name = '888' test() inner()#888 print(name) #alex func() print(name) #老男孩
1.函数也可以认为是一个数据
2.函数内部的数据会不会混乱?
def func(): print(123) v1 = func func()#123 v1() #123
def func(): print(123) func_list = [func,func,func] for item in func_list: v = item() print(v) # 123 none 123 none 123 none 先执行函数,在返回值
def func(): #函数一般不当字典的key print(123) def bar(): print(666) info = {'k1':func,'k2':bar} info['k1']() #123 info['k2']()#123
混淆题:
def func(): print(123) func_list1 = [func(),func(),func()] #有返回值 func_list2 = [func,func,func] print(func_list2) print(func_list1) ''' def func(): return 12 info = { 'k1':func, 'k2':func() } print(info) #{'k1': <function func at 0x00000000028F4C18>, 'k2': 12}
def func(arg): arg() def show(): print(666) func(show) #666 def func(arg): v1 = arg() print(v1) #none def show(): print(666) #执行完了没有返回值 所以是none func(show) #666
def func(arg): print(arg) func(1) #1 def show(): return 999 func(show) #打印show函数所在的内存地址 func(show()) # 999
def func(arg): v1 = arg() print(v1) #none show的返回值是v1,所以v1是none def show(): print(666) result = func(show) #666 print(result) #none 谁调用的函数,返回值就给谁 #先计算func(show),所以先print666,因为func调用的是show函数,所以v1等于它的返回值none, # 然后在计算result,因为result调用的是func函数,所以result的结果是func的返回值none
面试题 def func(): print('话费查询') def bar(): print('宽带办理') def show(): print('流量查询') def text(): print('人工服务') def base(): print('流量包办理') info = { 'f1':func, 'f2':bar, 'f3':show, 'f4':text, 'f5':base, } choice = input('请选择你要的服务:') function_name = info.get(choice) if function_name: function_name() else: print('输入错误')
用于表示简单的函数
lambda表达式也称为匿名函数(不调用函数,内部代码不执行)
#三元运算,为了解决简单的if else的情况: if 1 ==1: a = 123 else: a = 456 a =123 if 1 ==1 else 456 #lambda表达式,为了表示简单函数的情况,如: def func(a1,a2): return a1 + a2 func = lambda a1,a2: a1+a2
func1 = lambda : 100 #没有参数,返回100 func2 = lambda x1 : x1 *10 func3 = lambda *args,**kwargs: len(args) +len(kwargs) v1 = func3(1,2,33) print(v1) #3 DATA = 100 func4 = lambda a1: a1 + 100 v1 = func4(1) print(v1) #101 DATA = 100 def func(): DATA = 1000 func4 = lambda a1: a1 + DATA v1 = func4(1) print(v1) func() #1001 func5 = lambda n1,n2: n1 if n1 > n2 else n2 v= func5(1,2) print(v)#2
练习题:
USER_LIST = [] func1 = lambda x: USER_LIST.append(x) #这行的返回值是none v1 = func1('alex') print(v1) #None print(USER_LIST) #['alex'] ''' #看是否有返回值,是看执行完这个之后是否返回东西,列表几乎所有的功能基本上返回值都是none,对于字符串所以的方法返回的都是一个新的返回值 def func(x): v = x.strip() return v result = func(' alxe ') print(result) #alex func1 = lambda x: v = x.split('l') v1 = func1('alex') print(v1t) #[a,lex] func_list = [lambda x: x.strip(),lambda y:y+199,lambda x,y:x+y] v1 = func_list[0](' alex ') print(v1) v2 = func_list[1](100) print(v2) v3 = func_list[2](1,2)
-
-
内置函数
-
len
-
open
-
range
-
id
-
type
-
输入输出:print、input
-
强制转换
-
dict()
-
list()
-
int()
-
str()
-
bool()
-
set()
-
-
数学相关
-
随机验证码 import random def get_random_code(length=6): data = [] for i in range(length): v = random.randint(65, 90) #生成一个范围内的随机验证码 data.append(chr(v)) return (''.join(data)) code = get_random_code() print(code)
import random#导入一个模块 v= random.randint(起始,终止) #得到一个随机数
-
1字节= 8位 0101的位置 IP:192,168,12,79-->四个字节通过点连接起来的,地址的范围是0-255 把IP = '192,168,12,79'中的每个十进制数转换成二进制并通过逗号连接起来生成一个心的字符串 IP = '192,168,12,79' ip_list = IP.split(',') # print(ip_list) ['192', '168', '12', '79'] result = [] for item in ip_list: result.append(bin(int(item))) print(','.join(result)) #0b11000000,0b10101000,0b1100,0b1001111 ##面试题 请将IP = '192,168,12,79'中的每个十进制数转换成二进制,把二进制拼接起来并转换成十进制 ip = '10.3.9.12' ip_list = ip.split('.') print(ip_list) result = [] for item in ip_list: result.append(bin(int(item)).replace('0b','').rjust(8,'0')) # print(result) data = int(''.join(result),base=2) print(data) # ip = '10.3.9.12' # print(int(''.join(bin(int(i))[2:].rjust(8,'0') for i in ip.split('.')),base=2)) ''' def ip(ip_add): ip_list = list() for i in ip_add.split('.'): #把地址用. 分割开 ip_list.append(bin(int(i)).replace('0b', '').rjust(8, '0')) #bin(int(i))是把每一个十进制的ip转换成二进制,replace('0b', '')把二进制中0b的位置替换成空, # .rjust(8,'0')是指前面替换成空的位置用八个零填充 .rjust(width, 'fillchar') return int(''.join(ip_list), base=2) ip_add = input('输入一个IP地址:') print(ip(ip_add))
高级一点的内置函数
a:map,循环第二个参数的每个元素,然后让每个元素执行函数(第一个参数),将每个函数执行的结果保存到列表中并返回
map是有返回值的不影响v1 v1 = [11,22,33,44] #第一个参数必须是一个函数 #第二个参数必须是可迭代的类型,可被for循环的(列表,字符串,字典,元组,集合),map会循环一个函数 def func(arg): print(arg) result = map(func,v1) #每循环一次会把函数的返回值添加到一个空列表中[none,none,none,none] print(list(result)) # v1 = [11,22,33,44] def func(arg): return arg + 100 result = map(func, v1) # 每循环一次会把函数的返回值添加到一个空列表中[none,none,none,none] print(list(result)) # [111, 122, 133, 144] ''' v1 = [11,22,33,44] result = map(lambda x:x+100,v1) print(result) #[111, 122, 133, 144] print(list(result)) #特殊对象
b:filter(过滤出想要的)
v1 = [11,22,33,44] result = map(lambda x:x+100,v1) print(result) #[111, 122, 133, 144] print(list(result)) #特殊对象 ''' v1 = [11,22,33,'ade',44,'xf'] #找到列表中的数字 def func(x): if type(x) == int: return True return False result = filter(func,v1) print(list(result)) #[11, 22, 33, 44] v1 = [11, 22, 33, 'ade', 44, 'xf'] # 找到列表中的数字 def func(x): # return True if type(x) ==int else False return type(x) ==int result = filter(func, v1) print(list(result)) # [11, 22, 33, 44] v1 = [11, 22, 33, 'ade', 44, 'xf'] # 找到列表中的数字 def func(x): result = filter(lambda x:type(x)==int,v1) print(list(result)) # [11, 22, 33, 44]
c:reduce(乘,除,加,减,得到一个数)
import functools v1 = [1,2,3,4,5] def func(x,y): return x+y #第一次返回是什么,在下一次执行的时候第一个数就是第一次返回的值 result = functools.reduce(func,v1) print(result) #15 result = functools.reduce(lambda x,y:x+y,v1) print(result)
def func(): print(123) def bar(): return func v = bar() v()#none
def bar(): def inner(): print(123) return inner v = bar() v() #123 v是inner
name = 'oldboy' def bar(): name = 'alex' def inner(): print(name) return inner v = bar() v() #alex
name = 'oldboy' def bar(name): def inner(): print(name) return inner v1= bar('alex') #开辟内存 [name = alex,inner] #闭包 为某个函数创建一个区域(内部变量供自己使用),为它以后执行提供数据 v2 = bar('eric')#开辟内存 [name = eric,inner] v1() #alex v2()#eric
函数执行的流程分析(函数在何时是由谁创建的,作用域就从这边开始找)
练习题 name = 'alex' def base(): print(name) def func(): name = 'eric' base() #调用了base func() #alex name = 'alex' def func(): name = 'eric' def base(): print(name) base() func() #eric name = 'alex' def func(): name = 'eric' def base(): print(name) base() func() #eric ''' name = 'alex' def func(): name = 'eric' def base(): print(name) return base base = func() base() #eric
面试题(重点)
info = [] def func(): print(item) for item in range(10): info.append(func) #item = 9 info[0]()#9 ''' info = [] def func(i): def inner(): print(i) return inner for item in range(10): info.append(func(item)) info[0]()#0 info[1]()#1 info[4]()#4
-
-
应用场景:想要为函数扩张功能时,可以选择用装饰器
-
def 外层函数(函数名): def 内层函数(*args,**kwargs):#表示函数可以接收任意参数 return 函数名 return 内层函数
@外层函数 def index(): pass index()
示例: #装饰器的编写 def x(func): #func表示被装饰的函数 def y(): ret = func() return ret return y @x #@的作用是执行x函数,把下面index函数当做参数 x(index) #第二步:将func的返回值重新赋值给下面的函数名,index = x(index) def index(): pass @x def mange(): pass #执行函数,自动触发装饰器 index()
def func(): pass v = 10 v = func def base(): print(1) def bar(): print(2) bar = base bar() #1
def func(arg): def inner(): arg() return inner def f1(): print(123) v1 = func(f1) v1() #123
def func(arg): def inner(): arg() #=f1 return inner def f1(): print(123) return 666 v1 = func(f1) result = v1() #执行inner函数 inner返回none/执行f1函数打印了123,return666没有人接收 print(result) #123 None ''' def func(arg): def inner(): return arg() #=f1 return inner def f1(): print(123) return 666 v1 = func(f1) result = v1() #执行inner函数 inner返回none/执行f1函数打印了123,return 666被接收了 print(result) #123 666
def func(arg): def inner(): v = arg() return v return inner #第一步:执行func函数并将下面的函数参数传递,相当于:func(index) #第二步:将func的返回值重新赋值给下面的函数名,index = func(index) @func def index(): print(123) return 666 print(index) #<function func.<locals>.inner at 0x00000000028AC168>
import time def wrapper(func): def inner(): star_time = time.time() v = func() end_time = time.time() print(end_time - star_time) return v return inner @wrapper def func1(): time.sleep(2) print(123) def func2(): time.sleep(1) print(123) def func3(): time.sleep(1.5) print(123) func1()
问题:为什么加*args,**kwargs?可以接收很多的参数
def wrapper(func): def inner(*args,**kwargs): return func(*args,**kwargs) return inner def index(): print(123) index() #123 def show(a1): print(a1+100) show(1) #101
def x(func): def inner(a1): return func(a1) return inner @x deef index(a1): pass 对于有一个参数的,装饰器中inner和func都有一个参数
def x(func): def inner(a1,a2): return func(a1,a2) return inner @x deef index(a1,a2): pass #index = inner index(1,2) 对于有两个个参数的,装饰器中inner和func都有两个参数 让参数统一的目的是为了给原来的index传参
给好几个函数写一个统一的装饰器
def wrapper(func): def inner(*args,**kwargs): return func(*args,**kwargs) return inner @wrapper def f1(): pass @wrapper def f2(a1): pass @wrapper def f3(a1,a2): pass
def wrapper(func): def inner(*args,**kwargs): data = func(*args,**kwargs) return data return inner @wrapper def f1(): print(123) #func = f1函数 inner =f1函数 执行f1函数,f1函数的返回值是none v1 = f1() #NOne
def wrapper(func): def inner(*args,**kwargs): data = func(*args,**kwargs) return 666 return inner @wrapper def f1(): print(123) #func = f1函数 inner =f1函数 v1 = f1() #
def wrapper(func): def inner(*args,**kwargs): data = func(*args,**kwargs) #666 data执行的是原来的f1函数,它的返回值是666 return inner @wrapper def f1(): print(123) return 666 v1 = f1() #none inner没有返回值
装饰器建议的写法:
def wrapper(func): def inner(*args,**kwargs): data = func(*args,**kwargs) return 666 return inner
def wrapper(func): def inner(*args,**kwargs): print('调用函数之前') data = func(*args,**kwargs) #执行原函数并获取返回值 print('调用函数之后') return data return inner @wrapper def f1(): print(123) return 666 f1() 5请为以下所有函数编写一个装饰器,添加上装饰器后可以实现: # 将被装饰的函数执行5次,讲每次执行函数的结果按照顺序放到列表中,最终返回列表。 ''' import random def wrapper(f): def inner(*args,**kwargs): value =[] for i in range(5): #循环执行原函数 data = f(*args,**kwargs) #执行原函数 value.append(data) return value return inner @wrapper def func(): return random.randint(1,4) reuslt = func() # 执行5次,并将每次执行的结果追加到列表最终返回给result print(reuslt)
#第一步:执行ret = xxx(index) #第二步:将返回值赋值给index = ret @xxx def index(): pass #第一步:执行v1 = xxx(9) #第二步:执行ret = v1(index) #第三步:index = ret @xxx(9) def index(): pass
练习题
#写一个带参数的装饰器,实现:参数是多少,被装饰的函数就执行多少次并把每次的结果返回一个列表 def xxx(arg): def wrapper(func): def inner(*args, **kwargs): value = [] for i in range(arg): data = func(*args, **kwargs) value.append(data) return value return inner return wrapper #先执行xxx(5)得到返回值wrapper,在通过wrapper = index执行代码,把返回值赋值给index @xxx(5) def index(): pass v = index() print(v) #[None, None, None, None, None] #写一个带参数的装饰器,实现:参数是多少,被装饰的函数就执行多少次并把最后一次的的结果返回 def xxx(arg): def wrapper(func): def inner(*args, **kwargs): data = func(*args, **kwargs) return data return inner return wrapper #先执行xxx(5)得到返回值wrapper,在通过wrapper = index执行代码,把返回值赋值给index @xxx(5) def index(): pass v = index() print(v) #[None] #写一个带参数的装饰器,实现:参数是多少,被装饰的函数就执行多少次并返回执行结果中最大的值 def xxx(arg): def wrapper(func): def inner(*args, **kwargs): value= 0 for i in range(arg): data = func(*args, **kwargs) if data >value: value = data return value return inner return wrapper #先执行xxx(5)得到返回值wrapper,在通过wrapper = index执行代码,把返回值赋值给index @xxx(5) def index(): pass v = index() print(v) #[None]
990个执行一个函数,另外10个执行一个函数 def xxx(arg): def wrapper(func): def inner(*args, **kwargs): if arg: return 123 return func(*args, **kwargs) return inner return wrapper @xxx(True) def index990(): pass @xxx(False) def index10(): pass
''' 目的:方便生成一个列表 格式: v1 = [i for i in 可迭代对象] v2 = [i for i in 可迭代对象 if 条件] #先做循环,为true时才append进去 ''' vals = [i for i in 'alex'] print(vals) #['a', 'l', 'e', 'x'] 格式: 变量 = [for循环的变量 for循环一个可迭代对象] v2 = [i+100 for i in range(10)] v3 = [99 if i >99 else 66 for i in range(10)] #[66, 66, 66, 66, 66, 66, 99, 99, 99, 99] def func(): pass v4 = [func for i in range(10)] #10个func v5 = [lambda : 100 for i in range(10)] result = v5[9]() #100 #新浪微博面试题 v6 = [lambda x: x*i for i in range(10)] v6是什么?是函数 v6[0](2)#18 ##面试题 def num(): return[lambda x:i*x for i in range(4)] #num()-->[函数,函数,函数,函数] i=3 x = 2 print([m(2) for m in num() ]) #[6,6,6,6] #####筛选 v7 = [i for i in range(10) if i>5] #先做循环,true才append进去 print(v7) #[6,7,8,9]
vals = {i for i in 'alex'}
v1 = {'k'+str(i):i for i in range(10)} print(v1)#{'k0': 0, 'k1': 1, 'k2': 2, 'k3': 3, 'k4': 4, 'k5': 5, 'k6': 6, 'k7': 7, 'k8': 8, 'k9': 9}
递归是自己调用自己,一直反复下去。(效率比较低)
def func(): print(1) func() func()
def func(i): print(1) func(i+1) func(1)#1,2,3,4,5....循环下去
def func(a,b): #1 #1 #2 #3 #5 print(b) #1 #1 func(b,a+b) #1 1 #1 2 func(0,1)
有无返回值的区别 def func(a): if a == 5: return 1000 result = func(a+1) + 10 return result v = func(1) #1040 def func(a): if a == 5: return 1000 result = func(a+1) + 10 v = func(1) #None