我对具有默认参数的函数有一些疑问。
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
默认参数:([1, 2, 3],)
322
1119
740
([1, 2, 3, 321, 1118, 739],)
参考数:3
303
参考数:2
默认参数: ([1, 2, 3, 321, 1118, 739, 302],)
303
默认参数: ([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]
对不起我的长解释。这是我的问题:
这是一个问题吗?我的模块粉碎 my_list 变量的字典,然后现在 my_list 变量的默认地址比以前的要高。然后在其主体中使用名为 my_list 的全局变量的函数正在更改(增长),而我的默认参数没有。为什么在执行表达式时
b
看不到命名的全局变量?我知道,与 my_list 有不同的地址(因为相互对象(如列表)现在保证引用不同的、唯一的、新创建的列表),但是为什么 Python 实现了当 b 是函数参数时看不到全局变量?你能全面解释一下吗?my_list
a + b[-1]
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, Sep 15 2010, 15:52:39)
[GCC 4.4.5]