1.如何用函数先定义后调用定义阶段只检测语法不执行代码调用阶段开始执行代码函数都有返回值定义时无参调用时也是无参定义时有参调用时也必须有参2.默认参数陷阱2.1针对可变数据类型不可变不受影响123456defc(a[]):a.append(1)print(a)c()c()c()结果[1][1, 1][1, 1, 1]123456defc(a[]):a.append(1)print(a)c([])c([])c([])结果[1][1][1]3.名称空间和作用域名称空间就是用来存放名字与值内存地址绑定关系的地方(内存空间)但凡查找值一定要通过名字,访问名字必须去查找名称空间名称空间分为三大类内置名称空间 存放的是python解释器自带的名字生命周期 在解释器启动时则生效,解释器关闭则失效全局名称空间 存放的是文件级别的名字生命周期 在解释器解释执行python文件时则生效,文件执行完毕后则失效局部名称空间 在函数内定义的名字生命周期 只在调用函数时临时产生该函数的局部名称空间,该函数调用完毕则失效加载顺序内置-全局-局部查找名字的顺序基于当前所在位置往上查找假设当前站在局部,查找顺序:局部-全局-内置假设当前站在全局,查找顺序:全局-内置名字的查找顺序,在函数定义阶段就已经固定死了(即在检测语法时就已经确定了名字的查找顺序),与函数的调用位置无关也就是说无论在任何地方调用函数,都必须回到当初定义函数的位置去确定名字的查找关系作用域 作用域指的就是作用的范围全局作用域 包含的是内置名称空间与全局名称空间中的名字特点 全局有效全局存活局部作用域 包含的是局部名称空间中的名字特点 局部有效临时存活global: 在局部声明一个名字是来自于全局作用域的可以用来在局部修改全局的不可变类型nonlocal: 声明一个名字是来自于当前层外一层作用域的可以用来在局部修改外层函数的不可变类型4.闭包函数定义在函数内部且包含对外部函数的作用域名字的引用需要结合函数对象的概念将闭包函数返回到全局作用域去使用从而打破函数的层级限制闭包函数提供了一种为函数体传值的解决方案1234567deffunc():nameegondefinner():print(name)returninnerinnerfunc()inner()5.函数的参数5.1定义阶段位置形参在定义阶段从左往右的顺序依次定义的形参默认形参在定义阶段已经为其初始化赋值关键字参数自由主题可变长度的形参args溢出的位置参数打包成元组给接受赋给args的变量名命名关键字参数放在*和之间的参数必须按照keyvalue形式传值可变长度的位置形参kwargs溢出的关键字实参打包成字典给**接受赋给变量kwargs形参和实参关系 在调用函数时会将实参的值绑定给形参的变量名这种绑定关系临时生效在调用结束后就失效了5.2调用阶段位置实参调用阶段按照从左往右依次传入的传入的值会与形参一一对应关键字实参在调用阶段按照keyvalue形式指名道姓的为形参传值实参中带*的再传值前先将打散成位置实参再进行赋值实参中带的**在传值前先将其打散成关键字实参再进行赋值6.装饰器闭包函数的应用装饰器就是用来为被装饰器对象添加新功能的工具**注意:**装饰器本身可以是任意可调用对象,被装饰器的对象也可以是任意可调用对象为何使用装饰器**开放封闭原则:**封闭指的是对修改封闭,对扩展开放6.1装饰器的实现必须遵循两大原则1. 不修改被装饰对象的源代码2. 不修改被装饰器对象的调用方式装饰器的目标:就是在遵循1和2原则的前提下为被装饰对象添加上新功能6.2装饰器语法糖在被装饰对象正上方单独一行写装饰器的名字python解释器一旦运行到装饰器的名字,就会调用装饰器,然后将被装饰函数的内存地址当作参数传给装饰器,最后将装饰器调用的结果赋值给原函数名 fooauth(foo) 此时的foo是闭包函数wrapper6.3无参装饰器123456789101112131415importtimedeftimmer(func):defwrapper(*args,**kwargs):start_timetime.time()resfunc(*args,**kwargs)stop_timetime.time()print(run time is %s%(stop_time-start_time))returnresreturnwrappertimmerdeffoo():time.sleep(3)print(from foo)foo()6.4有参装饰器123456789101112131415161718192021defauth(driverfile):defauth2(func):defwrapper(*args,**kwargs):nameinput(user: )pwdinput(pwd: )ifdriverfile:ifnameegonandpwd123:print(login successful)resfunc(*args,**kwargs)returnreselifdriverldap:print(ldap)returnwrapperreturnauth2auth(driverfile)deffoo(name):print(name)foo(egon)7.题目123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208#题目一dbdb.txtlogin_status{user:None,status:False}defauth(auth_typefile):defauth2(func):defwrapper(*args,**kwargs):iflogin_status[user]andlogin_status[status]:returnfunc(*args,**kwargs)ifauth_typefile:withopen(db,encodingutf-8) as f:diceval(f.read())nameinput(username: ).strip()passwordinput(password: ).strip()ifnameindicandpassworddic[name]:login_status[user]namelogin_status[status]Trueresfunc(*args,**kwargs)returnreselse:print(username or password error)elifauth_typesql:passelse:passreturnwrapperreturnauth2auth()defindex():print(index)auth(auth_typefile)defhome(name):print(welcome %s to home%name)# index()# home(egon)#题目二importtime,randomuser{user:None,login_time:None,timeout:0.000003,}deftimmer(func):defwrapper(*args,**kwargs):s1time.time()resfunc(*args,**kwargs)s2time.time()print(%s%(s2-s1))returnresreturnwrapperdefauth(func):defwrapper(*args,**kwargs):ifuser[user]:timeouttime.time()-user[login_time]iftimeout user[timeout]:returnfunc(*args,**kwargs)nameinput(name: ).strip()passwordinput(password: ).strip()ifnameegonandpassword123:user[user]nameuser[login_time]time.time()resfunc(*args,**kwargs)returnresreturnwrapperauthdefindex():time.sleep(random.randrange(3))print(welcome to index)authdefhome(name):time.sleep(random.randrange(3))print(welcome %s to home %name)index()home(egon)#题目三简单版本importrequestsimportoscache_filecache.txtdefmake_cache(func):defwrapper(*args,**kwargs):ifnotos.path.exists(cache_file):withopen(cache_file,w):passifos.path.getsize(cache_file):withopen(cache_file,r,encodingutf-8) as f:resf.read()else:resfunc(*args,**kwargs)withopen(cache_file,w,encodingutf-8) as f:f.write(res)returnresreturnwrappermake_cachedefget(url):returnrequests.get(url).text# resget(https://www.python.org)# print(res)#题目四:扩展版本importrequests,os,hashlibengine_settings{file:{dirname:./db},mysql:{host:127.0.0.1,port:3306,user:root,password:123},redis:{host:127.0.0.1,port:6379,user:root,password:123},}defmake_cache(enginefile):ifenginenotinengine_settings:raiseTypeError(egine not valid)defdeco(func):defwrapper(url):ifenginefile:mhashlib.md5(url.encode(utf-8))cache_filenamem.hexdigest()cache_filepathr%s/%s%(engine_settings[file][dirname],cache_filename)ifos.path.exists(cache_filepath)andos.path.getsize(cache_filepath):returnopen(cache_filepath,encodingutf-8).read()resfunc(url)withopen(cache_filepath,w,encodingutf-8) as f:f.write(res)returnreselifenginemysql:passelifengineredis:passelse:passreturnwrapperreturndecomake_cache(enginefile)defget(url):returnrequests.get(url).text# print(get(https://www.python.org))print(get(https://www.baidu.com))#题目五route_dic{}defmake_route(name):defdeco(func):route_dic[name]funcreturndecomake_route(select)deffunc1():print(select)make_route(insert)deffunc2():print(insert)make_route(update)deffunc3():print(update)make_route(delete)deffunc4():print(delete)print(route_dic)#题目六importtimeimportosdeflogger(logfile):defdeco(func):ifnotos.path.exists(logfile):withopen(logfile,w):passdefwrapper(*args,**kwargs):resfunc(*args,**kwargs)withopen(logfile,a,encodingutf-8) as f:f.write(%s %s run\n%(time.strftime(%Y-%m-%d %X),func.__name__))returnresreturnwrapperreturndecologger(logfileaaaaaaaaaaaaaaaaaaaaa.log)defindex():print(index)index()到此这篇关于Python必备技巧之函数的使用详解的文章就介绍到这了