python中的def函数括号⾥的默认值_Python中的默认参数值Python对默认参数值的处理⽅法是少有的⼏个易使⼤多数新⼿Python程序员犯错的地⽅之⼀。(通常只犯⼀次)
导致困惑的地⽅是当你使⽤“可变”对象作为(参数的)默认值时的(程序)⾏为。(可变)也就是说值可以原地修改,像列表或字典。
看下⾯的例⼦:
就像你看到的那样,列表变得越来越长。如果你查看列表的ID,你会发现函数实际上总是返回同⼀个对象。
原因很简单:函数在每次调⽤时总是使⽤同⼀个对象。我们做的修改⾏为有“粘性”。
为什么会这样?
属于函数定义的默认参数值当且仅当“def”语句执⾏时求值。请看:
语⾔参考中的相关章节。
要注意Python中的“def”语句是可执⾏的,⽽且默认参数是在“def”语句的环境下求值的。如果“def”语句执
⾏了多次,那么它每次将产⽣新的函数对象(对象会带着全新的默认值)。下⾯我们会看到这样的例⼦的。
那要怎么做?
迂回⽅法是,就像其他⼈已经提到了的,使⽤占位符值来替代默认值。None是⼀个常⽤的值:
如果你需要处理任意对象(包括None),你可以使⽤哨兵对象:
在很早以前,即在“object”对象引⼊之前,有时你会看到像下⾯这样的代码:
这个代码⽤于创建⼀个具有唯⼀ID的对象;这对中括号([])在每次执⾏时产⽣新的列表。python新手代码例子
对可变默认参数的合法(合理)使⽤
最后,要提到很多⾼级的Python代码经常使⽤这个机制的好处。例如,假设你要在⼀个循环⾥创建了⼀堆UI按钮,⽽你可能会使⽤像下⾯这样的代码:
这样你会发现所有的回调函数都打印出相同的值(在这个情况下,很可能是9)。原因是Python的嵌套作⽤域是绑定到变量的,⽽不是绑定到对象值的。所以所有的回调函数实例将会看到当前(也是最后)的变量“i”的值。为了修正这个问题,使⽤下⾯的代码:
那个“i=i”的步伐将绑定参数“i”(⼀个局部变量)到当前的外部变量“i”的值。
两个其他的例⼦使⽤的是局部缓存:
(这对某些递归算法很好)
另⼀个例⼦,对应⾼度优化的代码,对全局名字的局部重新绑定:
详细来说,这是怎么⼯作的?
当Python执⾏“def”语句时,它使⽤⼀些已有的东西(包括编译了的函数体的代码和当前的名字空间),然后创建出⼀个新的函数对象。当它做这个的时候,默认值也会被求值。
这些各种各样的组件也能作为函数对象的属性⽽访问。使⽤我们先前定义过的函数:
由于你可以访问它们,因⽽你也可以修改它们:
当然,这可不是我推荐的正常使⽤⽅法。
另⼀个重置默认值的⽅法就是简单的重新执⾏⼀下那个相同的“def”语句。Python会重新创建⼀个新的到这个代码对象绑定,重新计算默认值,然后将这个函数对象赋值给同以前⼀样的那个变量。但是要
着重指出,请在你确切知道你在做什么的时候才能这么做。
最后,如果你刚好有函数各个部分,⽽不是函数本⾝,你可以使⽤new模块中的function类来创建你⾃⼰的函数对象。
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论