具有默认参数的函数问题
我对有默认参数的函数有一些疑问。
import sys
from random import randint
my_list = [1,2,3]
def Veli(a, b = my_list):
my_list.append(randint(1,1500))
print a + b[-1]
print "Number of Refs:", sys.getrefcount(my_list)
print "Def args:", Veli.func_defaults
Veli(1) # This is 4
Veli(1) # We almost always obtain different result because of randint
Veli(1) # Again different results.
print Veli.func_defaults
print "Number of Refs:", sys.getrefcount(my_list)
Veli(1)
my_list = [-5] # old my_list has different address
print "Number of Refs:", sys.getrefcount(my_list) # Less than previous
print "Def args:", Veli.func_defaults
Veli(1) # Now gives same results.
print "Def args:", Veli.func_defaults
Veli(1) # Same result again...
输出:(当然,有些数字取决于randint返回的值。)
参考数量:3
Def args:([1,2,3],)
322
1119
740
([1,2,3,321,1118,739],)
参考数量:3
303
参考数量:2
Def args:([1,2,3,321,1118,739,302],)
303
Def args:([1,2,3,321,1118,739,302],)
303
以下代码为您提供的数字小于前一个,因为b和my_list不再引用相同的地址。
print "#ref:", sys.getrefcount(my_list) # Less than previous
现在,我们有一种方法(唯一的方法?)来达到b,函数的默认参数:
Veli.func_defaults[0]
对我的长篇解释感到抱歉。这是我的问题:
这是一个问题吗?我的模块字典crush my_list变量然后现在my_list变量具有默认地址而不是之前的地址。然后在其正文中使用名为my_list的全局变量的函数正在改变(增长)而我的默认参数不是。当执行a + b[-1]
表达式时,为什么不能b
看到名为my_list
的全局变量?我知道,b
与my_list有不同的地址(因为相互对象(如list)保证现在引用不同的,唯一的,新创建的列表),但为什么Python实现使得当b是函数时b
看不到全局变量参数呢?你能全面解释一下吗?
有没有办法用Veli.func_defaults [0]获得相同的结果?然后执行此代码,我想更改名为Veli的函数的默认参数。我不能用my_list执行此操作,因为my_list和b具有不同的地址。一种方法是更改列表的元素Veli.func_defaults [0]。有什么不同的方式吗?
(它与上面的代码没那么相关)如何获取变量的地址?例如,如何获得b
的地址?我使用__hash__
等内置功能,但应该有更合适的方法。
笔记:
a)这些代码可能因任何原因无用,但我想学习意见。
b)关于linux2的Python 2.6.6(r266:84292,2010年9月15日,15:52:39)[GCC 4.4.5]
没有找到相关结果
已邀请:
2 个回复
街茬
对物体的引用ѭ4恰好在那时指的是
。 Python从不使用pass-by-reference - 变量保存引用,并且这些引用始终按值传递。因此,实际上保存在
中的一个参考(指针)被复制,没有人记得它来自哪里或烦人更新它。 不太清楚你在问什么,请澄清一下。如果没有通过第二个参数,
将是
,但如果通过则明显不同(好吧,当然除非呼叫者访问
......你应该假设他没有)。你可以按照另一个答案的建议做出
默认为
并使用全球
如果
- 这将在每次通话时为您提供新的,更新的参考副本。也许你应该写一个类并保持默认值为
的属性并应用通常的
成语。 内置功能
。实际上,它的实现定义了它返回的内容(不必是地址),只要它是一个表示对象标识的整数,即不同的对象(具有重叠的生命周期)具有不同的
并且同一个对象总是给出同一
在其一生中。 CPython选择的简单返回值是地址。
磐剩
必然指向
。当您稍后将
更改为指向其他对象时,
不受影响。 要获得“延迟绑定”,您需要编写如下函数: