当前位置: 首页 > 后端技术 > Python

【Python教程】11.高级语法

时间:2023-03-25 20:47:23 Python

概述不定参数迭代器匿名方法函数式编程装饰器练习不定参数我们在前面学习的框架中经常会用到不定参数。不确定参数中,传入的参数个数是任意的,可以是0个、1个、2个,也可以是无数个。两种形式:*args,**kw。deffunc(*args):#可变参数print(len(args))#可变参数个数print(args)#参数是一个元组print(args[0])#参数获取func('arg1','arg2',4)#可以写任意数量的参数输出:单个星号*args表示连续的一段参数,可以写任意数量的参数。实际传入的变量是一个元组。可以使用基本的元组操作来获取参数信息。deffunc2(**kw):#字典变量参数print(kw)#参数是一个字典print(kw['a'])#获取参数func2(a=1,b=2,c=3)#是写入任意数量的赋值参数输出:两个星号**kw可以写入任意数量的命名参数。实际参数作为字典传入。组合使用:两个不确定参数可以单独使用,也可以组合使用。deffunc3(name,*args)deffunc3(name,**kw)deffunc3(name,*args,**kw)需要注意的是,必须严格按照上面的顺序。解包:*和**其实是一种解包语法。t=[1,2,3,4,5,6]func(*t)#将列表解压成参数d={'a':1,'b':2}func2(**d)#解压dictionary参数解包后,其参数结构与不确定参数相同。在实战中,我们以数据库连接为例,连接信息可以单独保存,方便维护。importpymysqlconnect_info={'host':'127.0.0.1','port':3306,'user':'root','password':'123456','db':'test'}conn=pymysql.connect(**connect_info)IteratorIterator:记录遍历位置。l=[1,2,3,4,5]it=iter(l)#创建一个迭代器i=next(it)#获取下一个iter方法从列表中创建一个迭代器。next方法是迭代器的唯一方法,它不断获取下一个值。迭代器遍历:whileloopi=next(it)#获取下一个whileTrue:#下一个循环输出print(i)try:i=next(it)exceptStopIteration:breakforloop#迭代器类型用于forloopfori其中:当print(i)迭代到无值时,将抛出StopIteration异常。迭代器是循环语句操作能否执行的标志。列表等数据类型具有迭代器。创建迭代器类:__iter__、__next__。可以通过在任何类中重写这两个方法来实现迭代器。类PowerIter:def__init__(self,power,max=1000):self.data=0self.power=powerself.max=maxdef__iter__(self):returnselfdef__next__(self):self.data+=1ret=self.data**self.powerifret>self.max:raiseStopIterationreturnret创建一个可以生成N次方列表的迭代器。iter=PowerIter(2)print(next(iter))print(next(iter))foriiniter:print(i)实例化对象后,可以通过next调用__next__。也可以直接在循环语句中使用。这种方式避免了太多的内存使用。生成器:产量。生成的是迭代器。defpower_iter(power,max=1000):data=0whileTrue:data+=1ret=data**powerifret>max:returnyieldret#generator通过methods实现了和前面iterator一样的功能。x=power_iter(2)print(next(x))print(next(x))yield是一种返回,但是还没有跑完。由next调用,直到真正的返回将停止生成器。该方法结束。迭代器可以转换为列表。这时迭代器会继续执行next直到结束,并将结果放入list中。print(list(x))输出:也可以直接通过列表的特殊语法生成一个列表。[i**2foriinrange(100)]匿名方法匿名方法:定义在lambda开头的方法没有方法名。f1=lambda:0#无参数f2=lambdax:xifx>0else0#单参数f3=lambdax,y:x+y#多参数f3(1,2)#调用lambda后跟参数,您可以跟上多个参数。冒号后面是方法实现,不需要返回,直接返回。在调用方面,匿名方法可以保存在变量中,然后用变量调用。这种将方法作为变量的编程方式称为函数式编程。函数式编程函数式编程:使用方法本身作为变量。Lambda是函数式编程的基本单元之一。事实上,所有的方法都可以赋值给变量。f=lambdax:x*xdeffunc(x):returnx*xprint(f)print(func)x=func#赋值输出:打印的内容说明是一个方法。方法可用于赋值,它们的调用方式与lambda调用相同。作为参数的方法:如GUI中的回调方法命令。deffuncx(f):returnf(1)#调用传入方法print(funcx(f))#将方法作为参数传给filter:filter.x=filter(lambdad:d%2,range(10))print(list(x))参数1:用于过滤的方法。当返回True时,将放置返回值。参数2:要过滤的列表。返回一个迭代器,转换为列表。MapReduce:映射、缩减。参数1是方法,参数2是迭代对象。l=[3,4,1,2,-1,-2,-3]y=map(lambdax:abs(x),l)#映射操作print(list(y))fromfunctoolsimportreducez=reduce(lambdaa,b:a+b,l)#Reduce操作print(z)输出:map对每个迭代对象执行方法【单参数】,返回迭代器。reduce从第一个到最后一个累加迭代对象,累加方法带两个参数得到一个结果。比如加法的时候,先把元素1和元素2相加得到结果,再和元素3相加,以此类推。方法作为返回值:在方法内定义一个方法作为返回值。deff():defg():#在方法中定义一个方法print('g')returng#返回一个方法f()#获取方法f()()#要调用返回的方法,需要先获取方法,再调用。我们还在GUI选择框中使用此语法checkbutton=tk.Checkbutton(root,text="selectionbox",variable=check,command=lambda:checkbutton_select(check))。一种用法是执行延迟计算。[懒加载]deflazy_sum(*args):def_sum():returnsum(args)return_sumret=lazy_sum(1,2,3)#不是立即计算ret()#下面介绍调用Decoration时的计算结果器也是其用途之一。DecoratorDecorator:对方法进行装饰,其本质是方法的嵌套。defdeco(f):defwrapper():print('deco')returnf()returnwrapperdeffunc():print('func')deco(func)()首先定义一个参数为方法,然后返回值也是方法的方法deco。deco中定义了一个wrapper方法,可以用来装饰传入的方法。重定义的方法除了调用原来的方法外,还增加了新的东西。最后执行的是带有嵌套装饰的新方法。这种编程风格称为面向方面编程[AOP]。Python使用@语法来执行此操作。在方法中加上@deco,方法会自动变成deco(func)。@decodeffunc():print('func')func()deco是一个简单的装饰器。定义装饰器:fromfunctoolsimportwrapsdefdeco_name(f):@wraps(f)defwrapper(*args,**kwargs):#...pre-operation...ret=f(*args,**kwargs)#...postoperation...returnrereturnreturnwrapperdeco_name替换为装饰器名称。在预动作中,在方法之前编写要执行的代码。在post-action中,写方法执行后的动作。带参数装饰器:制作带参数装饰器的方法是在原来的装饰器上再嵌套一层,传入参数。defdeco_name_args(a,b):defdecorator(f):@wraps(f)defwrapper(*args,**kwargs):#...预操作...ret=f(*args,**kwargs)#...后操作...returnretreturnwrapperreturndecorator可以和参数一起使用。@deco_name_args(1,2)defff():pass实战场景:切面编程在web开发中比较常见,使用场景也很多。日志导入日志,timedeflog(f):@wraps(f)defwrapper(*args,**kwargs):logging.info('{}call{}'.format(time.time(),f.__name__))returnfunc(*args,**kwargs)returnwrapper在方法前加上这个装饰器,每次执行都会记录一个执行日志。登录验证defauth(f):@wraps(f)defwrapper(*args,**kwargs):auth=kwargs['auth']#获取验证信息ifnotauth:#验证失败return#失败处理returnf(*args,**kwargs)returnwrapper在每次执行方法前进行登录验证,失败则进行处理。实践github:https://github.com/lvancer/co...