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

翻译:《实用的Python编程》07_03_Returning_functions

时间:2023-03-25 19:29:59 Python

上一节(7.2匿名函数)|下一节(7.4装饰器)7.3返回函数本节介绍使用函数创建其他函数的思想。简介考虑以下函数:defadd(x,y):defdo_add():print('Adding',x,y)returnx+yreturndo_add这是一个返回其他函数的函数。>>>a=add(3,4)>>>a>>>a()Adding347Localvariables请观察内部函数如何引用外部函数定义的变量。defadd(x,y):defdo_add():#`x`和`y`定义在`add(x,y)`之上print('Adding',x,y)returnx+yreturndo_add进一步观察你会发现在add()函数结束后这些变量还活着。>>>a=add(3,4)>>>a>>>a()Adding34#这些值从哪里来?7闭包当内层函数返回结果时,内部函数称为闭包。defadd(x,y):#`do_add`是一个闭包defdo_add():print('Adding',x,y)returnx+yreturndo_add基本特征:闭包保留函数运行所需的内容适当地在未来所有变量的值。闭包可以被认为是一个函数,它有一个额外的环境来保存它所依赖的变量的值。使用闭包虽然闭包是Python的一项基本功能,但它们的用法通常很微妙。常见应用:回调函数中使用。延迟计算。装饰函数(稍后描述)。延迟计算考虑这样一个函数:defafter(seconds,func):importtimetime.sleep(seconds)func()用法示例:defgreeting():print('HelloGuido')after(30,greeting)after(delay30秒后)执行给定的函数...闭包带有附加信息。defadd(x,y):defdo_add():print(f'Adding{x}+{y}->{x+y}')returndo_adddefafter(seconds,func):importtimetime.sleep(seconds)func()after(30,add(2,3))#`do_add`有引用x->2和y->3代码重复闭包也可以用作避免大量代码重复的技术。练习练习7.7:使用闭包避免重复闭包更强大的功能之一是它们能够生成重复代码。让我们回顾练习5.7中的代码,它定义了带有类型检查的属性:classStock:def__init__(self,name,shares,price):self.name=nameself.shares=sharesself.price=price..@propertydefshares(self):returnself._shares@shares.setterdefshares(self,value):ifnotisinstance(value,int):raiseTypeError('Expectedint')self._shares=value...与其一遍又一遍地键入代码,不如使用闭包自动创建代码。请创建一个typedproperty.py文件并将以下代码放入文件中:#typedproperty.pydeftypedproperty(name,expected_type):private_name='_'+name@propertydefprop(self):returngetattr(self,private_name)@prop.setterdefprop(self,value):ifnotisinstance(value,expected_type):raiseTypeError(f'Expected{expected_type}')setattr(self,private_name,value)returnprop现在,通过定义这样的类试试出来:fromtypedpropertyimporttypedpropertyclassStock:name=typedproperty('name',str)shares=typedproperty('shares',int)price=typedproperty('price',float)def__init__(self,name,shares,price):self.name=nameself.shares=sharesself.price=price尝试创建一个实例并验证类型检查是否有效:>>>s=Stock('IBM',50,91.1)>>>s.name'IBM'>>>s.shares='100'...应该得到一个TypeError...>>>练习7.8:简化函数调用在上面的例子中,用户可能会发现诸如typedproperty('shares',int)方法有点冗长——尤其是在多次调用时。请将以下定义添加到您的typedproperty.py文件中。String=lambdaname:typedproperty(name,str)Integer=lambdaname:typedproperty(name,int)Float=lambdaname:typedproperty(name,float)现在重写Stock类以使用以下函数:classStock:name=String('name')shares=Integer('shares')price=Float('price')def__init__(self,name,shares,price):self.name=nameself.shares=sharesself.price=price,Feeling现在好多了。这里的要点是:闭包和lambda经常用于简化代码和消除烦人的代码重复。这通常非常好。练习7.9:付诸实践重写stock.py文件中的Stock类以使用上面显示的类型化属性。目录|上一节(7.2匿名函数)|下一节(7.4装饰器)注:完整翻译见https://github.com/codists/practical-python-zh

猜你喜欢