h****r 发帖数: 2056 | 1 比如function的default value, 如果给的是mutable value, 从此就产生了一个static
object, 如果在function里对这个default value进行了修改,下次再call这个
function with default value, default value就不再是原定义的那个,而是上次被
call修改后的。 |
g****t 发帖数: 31659 | 2 写成=nan
然后函数体里面写成 if x= = nan : xxxxx ? |
L***s 发帖数: 1148 | 3 其实所有 python objects 都是直接 malloc 在 heap 上的,并没有 static object
的概念
清理全靠 gc。cpython 是引用计数gc,不过引用计数只是实现的副产品,并不在 lang
specs 里
比如 pypy 这类的 tracing jit 就不依赖引用计数
static
【在 h****r 的大作中提到】 : 比如function的default value, 如果给的是mutable value, 从此就产生了一个static : object, 如果在function里对这个default value进行了修改,下次再call这个 : function with default value, default value就不再是原定义的那个,而是上次被 : call修改后的。
|
L***s 发帖数: 1148 | 4 mutability是正交的另一个问题
lang
【在 L***s 的大作中提到】 : 其实所有 python objects 都是直接 malloc 在 heap 上的,并没有 static object : 的概念 : 清理全靠 gc。cpython 是引用计数gc,不过引用计数只是实现的副产品,并不在 lang : specs 里 : 比如 pypy 这类的 tracing jit 就不依赖引用计数 : : static
|
g****t 发帖数: 31659 | 5 这个default parameters的特点挺有用的。例如
可以拿到函数被调用了多少次这个理论上在函数外的信息。
如果愿意,还可以放别的此次调用过程的状态,在下次调用的时候用。
但这种东西我从不用。
: 其实所有 python objects 都是直接 malloc 在 heap 上的,并没有 static
object
: 的概念
: 清理全靠 gc。cpython 是引用计数gc,不过引用计数只是实现的副产品,并不
在 lang
: specs 里
: 比如 pypy 这类的 tracing jit 就不依赖引用计数
: static
【在 L***s 的大作中提到】 : mutability是正交的另一个问题 : : lang
|
h****r 发帖数: 2056 | 6 你说偏了。
lang
【在 L***s 的大作中提到】 : 其实所有 python objects 都是直接 malloc 在 heap 上的,并没有 static object : 的概念 : 清理全靠 gc。cpython 是引用计数gc,不过引用计数只是实现的副产品,并不在 lang : specs 里 : 比如 pypy 这类的 tracing jit 就不依赖引用计数 : : static
|
L***s 发帖数: 1148 | 7
这个问题在别处有讨论过
http://www.newsmth.net/bbstcon.php?board=Python&gid=84864
发信人: pulo (普洛米·我们的民族从来不缺乏苦难), 信区: Python
标 题: Re: 关于空list做默认参数的一个疑问
发信站: 水木社区 (Thu Dec 29 04:32:28 2011), 转信
一个函数的默认参数是该函数(对象)的一个属性,存在一个叫func_defaults
的tuple里,而函数(类)本身在def时就实例化了,其func_defaults属性
有可能在多次函数调用过程中改变。
拿楼主的例子来说:
>>> def test1( x=[] ):
... print(type(x))
... x.append(0)
... return x
...
>>> test1.func_defaults
([],)
>>> test1()
[0]
>>> test1.func_defaults
([0],)
>>> test1()
[0, 0]
>>> test1.func_defaults
([0, 0],)
因为x绑定test1.func_defaults[0] —— 一个(mutable) list,
所以x.append(0)实际更改了默认参数的值。这种副作用不是我们想要的。
要避免这点,可以像hgoldfish所建议的那样(如下test2):
>>> def test2( x=None ):
... print(type(x))
... if x is None : x = []
... print(type(x))
... x.append(0)
... return x
...
>>> test2.func_defaults
(None,)
>>> test2()
[0]
>>> test2.func_defaults
(None,)
>>> test2()
[0]
>>> test2.func_defaults
(None,)
x=[]只是把x重新绑定到[],而并不改变test2.func_defaults[0],
于是上述副作用得以避免。
(PS. if x is None : x = [] 可以简写为 x = x or [])
同理,下列写法也可以避免该副作用:
>>> def test3( x=[] ):
... if not x : x = []
... x.append(0)
... return x
...
>>> test3()
[0]
>>> test3()
[0]
但那句if判断和默认参数放在一起,从语言层面总觉得有些脱裤子放屁之嫌……
楼主觉得问题的根源在于函数的默认参数可以在函数体中被有意或无意地修改,
而由于 函数早在定义时就被实例化 的特点,该修改有可能影响后续函数调用。
这个"feature"倒是很符合"动态语言"的特点,但楼主认为这一设计不好,
它并没有带来什么好处,误用的可能性倒是很大,而且错误不容易被发现……
【在 h****r 的大作中提到】 : 你说偏了。 : : lang
|