源码网商城,靠谱的源码在线交易网站 我的订单 购物车 帮助

源码网商城

Python中的默认参数详解

  • 时间:2021-03-14 00:29 编辑: 来源: 阅读:
  • 扫一扫,手机访问
摘要:Python中的默认参数详解
[b]文章的主题[/b] 不要使用可变对象作为函数的默认参数例如 list,dict,因为def是一个可执行语句,只有def执行的时候才会计算默认默认参数的值,所以使用默认参数会造成函数执行的时候一直在使用同一个对象,引起bug。 [b]基本原理[/b] 在 Python 源码中,我们使用def来定义函数或者方法。在其他语言中,类似的东西往往只是一一个语法声明关键字,但def却是一个可执行的指令。Python代码执行的时候先会使用 compile 将其编译成 PyCodeObject. PyCodeObject 本质上依然是一种静态源代码,只不过以字节码方式存储,因为它面向虚拟机。因此 Code 关注的是如何执行这些字节码,比如栈空间大小,各种常量变量符号列表,以及字节码与源码行号的对应关系等等。 PyFunctionObject 是运行期产生的。它提供一个动态环境,让 PyCodeObject 与运行环境关联起来。同时为函数调用提供一系列的上下文属性,诸如所在模块、全局名字空间、参数默认值等等。这是def语句执行的时候干的活。 PyFunctionObject 让函数面向逻辑,而不仅仅是虚拟机。PyFunctionObject 和 PyCodeObject 组合起来才是一个完整的函数。 下文翻译了一篇文章,有一些很好的例子。但是由于水平有限,有些不会翻译或者有些翻译有误,敬请谅解。如果有任何问题请发邮件到 acmerfight圈gmail.com,感激不尽 主要参考资料 书籍:《深入Python编程》 大牛:shell 和 Topsky Python对于函数中默认参数的处理往往会给新手造成困扰(但是通常只有一次)。 当你使用“可变”的对象作为函数中作为默认参数时会往往引起问题。因为在这种情况下参数可以在不创建新对象的情况下进行修改,例如 list dict。
[url=https://docs.python.org/2/reference/compound_stmts.html#function-definitions]https://docs.python.org/2/reference/compound_stmts.html#function-definitions[/url] 其中有下面一段 "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,e.g.:
[url=http://stackoverflow.com/questions/233673/lexical-closures-in-python]http://stackoverflow.com/questions/233673/lexical-closures-in-python[/url]) 另外的两个用途local caches/memoization
[u]复制代码[/u] 代码如下:
def calculate(a, b, c, memo={}):     try:         value = memo[a, b, c] # return already calculated value     except KeyError:         value = heavy_calculation(a, b, c)         memo[a, b, c] = value # update the memo dictionary     return value
(对一些递归算法非常好用) 对高度优化的代码而言, 会使用局部变量绑全局的变量:
[u]复制代码[/u] 代码如下:
import math def this_one_must_be_fast(x, sin=math.sin, cos=math.cos):     ...
[b]这是如何工作的?[/b] 当Python执行一条def语句时, 它会使用已经准备好的东西(包括函数的代码对象和函数的上下文属性),创建了一个新的函数对象。同时,计算了函数的默认参数值。 不同的组件像函数对象的属性一样可以使用。上文用到的'function'
[u]复制代码[/u] 代码如下:
>>> function.func_name 'function' >>> function.func_code <code object function at 00BEC770, file "<stdin>", line 1> >>> function.func_defaults ([1, 1, 1],) >>> function.func_globals {'function': <function function at 0x00BF1C30>, '__builtins__': <module '__builtin__' (built-in)>, '__name__': '__main__', '__doc__': None}
这样你可以访问默认参数,你甚至可以修改它。
[u]复制代码[/u] 代码如下:
>>> function.func_defaults[0][:] = [] >>> function() [1] >>> function.func_defaults ([1],)
然而我不推荐你平时这么使用。 另一个重置默认参数的方法是重新执行相同的def语句,Python将会和代码对象创建一个新的函数对象,并计算默认参数,并且把新创建的函数对象赋值给了和上次相同的变量。但是再次强调,只有你清晰地知道在做什么的情况下你才能这么做。 And yes, if you happen to have the pieces but not the function, you can use the function class in the new module to create your own function object.
  • 全部评论(0)
联系客服
客服电话:
400-000-3129
微信版

扫一扫进微信版
返回顶部