Python函数参数默认值的陷阱和原理深究(转)
add by zhj: 在Python文档中清楚的说明了默认参数是怎么工作的,如下
"Default parameter values are evaluated when the function definition is executed. This means that the expression is evaluated once, when the function is defined, and that the same “pre-computed” value is used for each call. This is especially important to understand when a default parameter is a mutable object, such as a list or a dictionary: if the function modifies the object (e.g. by appending an item to a list), the default value is in effect modified. This is generally not what was intended. A way around this is to use None as the default, and explicitly test for it in the body of the function
def whats_on_the_telly(penguin=None): if penguin is None: penguin = [] penguin.append("property of the zoo") return penguin
"
参见https://docs.python.org/2/reference/compound_stmts.html#function-definitions
这个问题的答案在 StackOverflow 上可以找到答案。这里将得票数最多的答案最重要的部分摘录如下:
Actually, this is not a design flaw, and it is not because of internals, or performance.
It comes simply from the fact that functions in Python are first-class objects, and not only a piece of code.
As soon as you get to think into this way, then it completely makes sense: a function is an object being evaluated on its definition; default parameters are kind of “member data” and therefore their state may change from one call to the other - exactly as in any other object.
In any case, Effbot has a very nice explanation of the reasons for this behavior in Default Parameter Values in Python.
I found it very clear, and I really suggest reading it for a better knowledge of how function objects work.
在这个回答中,答题者认为出于Python编译器的实现方式考虑,函数是一个内部一级对象。而参数默认值是这个对象的属性。在其他任何语言中,对象属性都是在对象创建时做绑定的。因此,函数参数默认值在编译时绑定也就不足为奇了。
然而,也有其他很多一些回答者不买账,认为即使是first-class object
也可以使用closure
的方式在执行时绑定。
This is not a design flaw. It is a design decision; perhaps a bad one, but not an accident. The state thing is just like any other closure: a closure is not a function, and a function with mutable default argument is not a function.
甚至还有反驳者抛开实现逻辑,单纯从设计角度认为:只要是违背程序猿基本思考逻辑的行为,都是设计缺陷!下面是他们的一些论调:
> Sorry, but anything considered “The biggest WTF in Python” is most definitely a design flaw. This is a source of bugs for everyone at some point, because no one expects that behavior at first - which means it should not have been designed that way to begin with.
The phrases “this is not generally what was intended” and “a way around this is” smell like they’re documenting a design flaw.
好吧,这么看来,如果没有来自于Python作者的亲自澄清,这个问题的答案就一直会是一个谜了。
相关文章
- python qt是什么_初识Python与Qt「建议收藏」
- python数组拼接字符串_Python练习题——数组拼接
- python socket recvfrom_Python:socket.recvfrom()不返回任何地址
- Python人工智能 | 十八.Keras搭建卷积神经网络及CNN原理详解
- python 流程、循环、异常、函数的高级用法(3.0)
- 经纬度距离计算 python_Python已知两坐标求距离
- Python的特点是什么_python具有的特点
- python调用通达信公式_通达信公式-主力雷达Python化[通俗易懂]
- 网工Python之路之netmiko模块实验(三)连接多机
- python抛出异常和捕获异常_Python异常
- python lambda表达式 if_Python学习-lambda表达式
- eval在python中是什么意思_如何在Python中使用eval ?
- 使用python实现单例模式的三种方式
- Python获取上个月最后一天的日期
- Python 数据类型详细篇:列表
- Python变量:变量定义作用类型及特征
- Python学习:6.python内置函数详解编程语言
- 利用python实现二分法和斐波那契序列详解编程语言
- Python结合MySQL实现信息交互(python与mysql交互)
- Linux升级:升级Python到最新版本(linux升级python版本)
- 安装Python MySQL驱动之快速指南(python安装mysql驱动)
- Python与Linux:开启互联网信息技术时代(python和linux)
- Python的面向对象思想分析