python 函数基础及装饰器
没有参数的函数及return操作
def test1(): print ("welcome") def test2(): print ("welcomt test2") return 0 def test3(): print("welcome test3") return 0,324,123,["test3","retest"] x = test1() #test1()表示执行,将执行结果(返回值)赋给变量x,会自动执行,并且由于test1 没有返回值(没有return操作),print的时候会打印none y = test2() #test2()执行,有print,也有return,由于return一个返回值,所以将return的值赋给变量y z = test3() print (x)
print (test1) ----test1没有执行,会打印test1的内存对象 print (y) print (z) 打印结果: welcome ----》x的打印结果 welcomt test2 ----》 y的打印结果 welcome test3 ----》 z的打印结果 None ----》x的打印结果 0 -----》y的打印结果 (0, 324, 123, ['test3', 'retest']) ---》z的打印结果 总结: 只有当函数赋给一个变量时,返回值才能打印出来 当返回值为0时(没有return操作):返回none 当返回值为1时(return n):返回n 当返回值大于1时(return a,b,bv,d):返回元组(a,b,bv,d)
带参数的函数
#位置参数调用 def test1(x,y): ##这里的x,y称之为形参 print (x) print (y) test1(1,2) ###这里的1,2称之为实参 注:形参和实参位置必须一一对应,##关键参数不能写在位置参数前面 ##关键字调用,与形参顺序无关 def test1(x,y): print (x) print (y) test1(y=1,x=2) 这里 y=1 将值传给y,x=2将值传给x
参数组(非固定参数)
#打印出一个元组(n个参数转换成元组) def test1(*args): ##传多个位置参数(及单个字符串类的参数),在参数不固定的情况下 print (args) test1(1,2,3,4,5) ##打印一个字典(n个参数转换成字典) def test1(**kwargs): ###接收多个关键字参数(及 键=值 类似的参数) print (kwargs) test1(name='aa',age=99,sex="man") 注:参数组一定要放在后面
高阶函数和嵌套函数
高阶函数说明:
- A:函数名当作实参传递给另一个函数
- B:函数名可以作为返回值
示例一:将函数名作为实参,传递给另一个函数
打印结果:
示例二:将函数名作为返回值
def bar(): print ('in the bar') return "xx"
def test1(func): print (func) return func #func为传递进来的函数名,作为返回值返回,return的结果一个内存对象 print (test1(bar)) ##打印bar的内存地址(test1(bar)即将bar的内存作为参数地址传给 test1,即func=bar,print (func)则打印的bar的内存地址,return也返回bar的内存地址) x=test1(bar) #这里bar不能加括号’()’,加了括号相当于把bar的返回值(相当于执行了bar,返回值为xx)传过去了,而不是传了一个函数
print (x()) #相当于执行了bar函数
执行结果:
<function bar at 0x0000020090A57F28> #print(func) 的值 <function bar at 0x0000020090A57F28> #return func的值 <function bar at 0x0000020090A57F28> X = test1(bar)的值 in the bar #x()的值 xx
示例:
retrun func 返回func的内存地址,t()相当于执行func,返回func函数的执行结果
嵌套函数
def foo(): print ('in the foo') def bar(): print ('in the bar') bar() foo() 打印结果: in the foo in the bar
装饰器
一、无参数装饰器
import time def timer(func): def deco(): start_time = time.time() func() #func()=test1() stop_time = time.time() print ("the func run time is %s" % (stop_time-start_time)) return deco ##返回deco的内存地址 @timer ### 等价于 test1=timer(test1),将test1函数的作为实参传给timer,所以test1=func,func()=test1() def test1(): time.sleep(3) print ("in the test1") print (timer(test1)) ##打印deco的内存地址#此时会打印deco的内存地址(因为,将test1函数传给timer,即func=test1,此时无论deco函数做啥操作,deco函数都没有执行,最后直接执行的是return deco,返回deco的内存地址) r = timer(test1) ##将deco的返回值(内存地址)赋给r,r() 则会执行deco这个函数(即deco()) r()
打印结果:
<function timer.<locals>.deco at 0x00000182EEAE9EA0> in the test1 the func run time is 3.000403881072998 the func run time is 3.003307342529297
实例二
import time def timer(func): def deco(): start_time = time.time() func() ###这里即执行 test1函数(func=test1) stop_time = time.time() print ("the func run time is %s" % (stop_time-start_time)) return deco @timer ### 等于 timer(test1),此时test1为一个内存对象 def test1(): time.sleep(3) print ("in the test1")
test1()
打印结果:
in the test1
the func run time is 3.0003435611724854
带参数的装饰器
带参数的装饰器即为在要被装饰的的函数里传入参数。例:
#所有参数可用*args,**kwargs代替
import time def timer(func): def deco(arg1): start_time = time.time() func(arg1) ###这里相当于执行test2(‘aaa’) stop_time = time.time() print ("the func run time is %s" % (stop_time-start_time)) return deco ##返回deco的内存地址 @timer def test2(aa): ##相当于将test2函数作为实参传给timer,即test2=timer(test2),test2=func ,func声明了deco函数,但没有执行,此时返回了deco的内存地址(deco加上括号“()”即可执行,所以test2()=deco()),
#所以 test2()传入一个参数执行等于deco()传入一个参数执行, time.sleep(2) print ('in the test2 %s ' % aa) #r1 = timer(test2) #r1("bb") ##根据上面说明,r1的结果为deco的内存地址,r1()执行就等于 deco()执行 test2('aaa') ##test2(‘aaa’) 即等于 deco(‘aaa’),所以deco函数也要加上参数
打印结果
in the test2 aaa the func run time is 2.0001180171966553
装饰器内部参数判断
#_*_coding:utf-8_*_ user_status = False #用户登录了就把这个改成True def login(auth_type): #把要执行的模块从这里传进来 def auth(func): def inner(*args,**kwargs):#再定义一层函数 if auth_type == "qq": _username = "alex" #模拟这是DB里存的用户信息 _password = "abc!23" #模拟这是DB里存的用户信息 global user_status if user_status == False: username = input("user:") password = input("pasword:") if username == _username and password == _password: print("welcome login....") user_status = True else: print("wrong username or password!") if user_status == True: return func(*args,**kwargs) # 看这里看这里,只要验证通过了,就调用相应功能 else: print("only support qq ") return inner #用户调用login时,只会返回inner的内存地址,下次再调用时加上()才会执行inner函数 return auth def home(): print("---首页----") @login('qq') def america(): #login() #执行前加上验证 print("----衣服专区----") def japan(): print("----化妆品专区----") @login('weibo') def henan(style): ''' :param style: 喜欢看什么类型的,就传进来 :return: ''' #login() #执行前加上验证 print("----河南专区----") home() # america = login(america) #你在这里相当于把america这个函数替换了 #henan = login(henan) # #那用户调用时依然写 america() # henan("3")
实例二
import time def timer(auth_type): def warpper(func): def deco(*args,**kwargs): if auth_type == "local": print ("welcome to local auth %s" % auth_type) start_time = time.time() func() stop_time = time.time() print ("the func run time is %s" % (stop_time-start_time)) else: print ("ni da ye de %s" % auth_type) return deco return warpper @timer(auth_type="ldap") ### 等于 test1=timer(test1) 这里timer加上了括号并传了参数,会将auth_type的值传给timmer函数,然后会执行warpper(), # 此时还没有调用(需要在最下面调用test1和test2的时候才会调用执行) def test1(): time.sleep(3) print ("in the test1") @timer(auth_type="local") ##这里的参数为作装饰器函数的参数 def test2(): print ("in the test2") test1() test2() 打印结果: ni da ye de ldap welcome to local auth local in the test2 the func run time is 0.0
双层装饰器
实例
user_info = {} def check_login(func): #### 检查是否的登陆 def inner(*args,**kwargs): if user_info.get('is_login',None): ####字典的get方法 r = func(*args,**kwargs) return r else: print ("please login") return inner def check_admin(func): ####检查是否是admin权限 def inner(*args,**kwargs): if user_info.get('user_type',None) == 2: ###2为管理员权限 r = func(*args,**kwargs) return r else: print("perssion deined") return inner @check_login ###双层装饰器 @check_admin ###双层装饰器 def index(): ###manage user login print ('welcome') @check_login def home(): ###普通用户登陆 def login(): c = input('user:') if c == 'admin': user_info['is_login'] = True user_info['user_type'] = 2 else: user_info['is_login'] = True user_info['user_type'] = 1 def main(): while True: a = input("1:denglu ,2:chakan xinxi ,3:super manager ") if a == "1": login() elif a == "2": home() elif a == "3": index() main() 执行说明: 在双层装饰器 处,从上往下执行,即,先执行@check_login加载到内存,在执行@check_admin,加载到内存,然后执行index函数 解析顺序(从下往上): 将@check_admin 和index函数作为一个参数传到@check_login函数下,即 check_login(func)下的func参数为 check_admin 和index函数 这个整体,
然后顺序执行,如果check_login的条件满足了(满足已经登陆了),在执行check_admin函数(是否满足为admin用户),如果check_admin函数也满足了,则执行index函数(执行index)