具有默认参数的函数问题

我对有默认参数的函数有一些疑问。
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]     
已邀请:
默认参数是函数定义时的边界。线
def Veli(a, b = my_list):
对物体的引用ѭ4恰好在那时指的是
func_defaults
。 Python从不使用pass-by-reference - 变量保存引用,并且这些引用始终按值传递。因此,实际上保存在
b
中的一个参考(指针)被复制,没有人记得它来自哪里或烦人更新它。 不太清楚你在问什么,请澄清一下。如果没有通过第二个参数,
b
将是
Veli.func_defaults[0]
,但如果通过则明显不同(好吧,当然除非呼叫者访问
func_defaults
......你应该假设他没有)。你可以按照另一个答案的建议做出
b
默认为
None
并使用全球
my_list
如果
b is None
- 这将在每次通话时为您提供新的,更新的参考副本。也许你应该写一个类并保持默认值为
self
的属性并应用通常的
(... = None): if ... is None: use = default
成语。 内置功能
id
。实际上,它的实现定义了它返回的内容(不必是地址),只要它是一个表示对象标识的整数,即不同的对象(具有重叠的生命周期)具有不同的
id
并且同一个对象总是给出同一
id
在其一生中。 CPython选择的简单返回值是地址。     
我建议你看一下这个现有的问题,因为你的问题基本上与同一个问题有关(尽管对这个主题的看法略有不同)。 如上所述,执行函数定义时,
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]
    

要回复问题请先登录注册