Python 具有默认参数的函数出现问题
我对具有默认参数的函数有一些疑问。Python 具有默认参数的函数出现问题,python,function,default-parameters,Python,Function,Default Parameters,我对具有默认参数的函数有一些疑问。 输出:(当然,一些数字取决于randint返回的值。) 参考文献数量:3 定义参数:([1,2,3],) 322 1119 740 ([1,2,33211118739],) 参考文献数量:3 303 参考文献数量:2 Def参数:([1,2,3,321,1118,739,302],) 303 Def参数:([1,2,3,321,1118,739,302],) 303 下面的代码给出的数字比前面的代码少,因为b和my_列表不再引用到同一地址 pri
输出:(当然,一些数字取决于randint返回的值。)
参考文献数量:3
定义参数:([1,2,3],)
322
1119
740
([1,2,33211118739],)
参考文献数量:3
303
参考文献数量:2
Def参数:([1,2,3,321,1118,739,302],)
303
Def参数:([1,2,3,321,1118,739,302],)
303
下面的代码给出的数字比前面的代码少,因为b和my_列表不再引用到同一地址
print "#ref:", sys.getrefcount(my_list) # Less than previous
现在,我们有一种方法(唯一的方法?)来达到b,函数的默认参数:
Veli.func_defaults[0]
对不起,我解释得太长了。以下是我的问题:
a+b[-1]
表达式时,为什么不能b
查看名为my_list
的全局变量?我知道,b
现在与我的_列表有不同的地址(因为),但是为什么Python的实现使得b
在b是函数参数时看不到全局变量?你能全面地解释一下吗b
的地址?我使用内置函数,比如\uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu
注: a) 无论出于什么原因,这些代码都可能是无用的,但我想了解一些意见。
b) linux2上的Python 2.6.6(r266:842921010年9月15日,15:52:39)
[GCC 4.4.5]
def Veli(a,b=my_list):
将当时引用的对象my_list
的引用放入func_defaults
中。Python从不使用按引用传递-变量保存引用,这些引用总是按值传递。因此,实际上保存在b
中的引用(指针)被复制,没有人记得它来自何处,也没有人费心更新它Veli.func\u默认值[0]
,但如果传递第二个参数,则会明显不同(当然,除非调用方访问func\u默认值
…您应该假设他没有)。您可以,正如另一个答案中所建议的,将b
设为默认值None
,如果b为None,则使用全局my_列表
——这将在每次通话中为您提供其参考的最新副本。也许您应该编写一个类,并将默认值保留为self
的属性,并应用通常的(…=None):如果。。。无:use=default
idiom
id
。实际上,它的实现定义了它返回的内容(不必是地址),只要它是一个表示对象标识的整数,即不同的对象(具有重叠的生存期)具有不同的id
,并且相同的对象在其生存期内始终提供相同的id
。CPython选择的easy返回值是地址b
绑定到指向my_list
。稍后更改my_list
以指向其他对象时,b
保持不变
要获得“惰性绑定”,您需要这样编写函数:
def Veli(a, b=None):
if b is None:
b = my_list # Gets value of my_list at call time
my_list.append(randint(1,1500))
print a + b[-1]
@ncoghlan:这是一次重要的演讲,但由于OP利用了这种行为,在这里并不完全相关。哎呀,我真的以为我在重读OP的问题后删除了它……你的解释比delnan更清楚,但你只回答了一个问题,而且delnan是第一个回答者。我选了他/她。谢谢你的回答
def Veli(a, b=None):
if b is None:
b = my_list # Gets value of my_list at call time
my_list.append(randint(1,1500))
print a + b[-1]