我使用以下代码在Python中修补对象的标识:
def f(var1):
print 'Within f and BEFORE modification: var1= '+str(var1)+', id= '+str(id(var1))
var1 = 10
print 'Within f and AFTER modification: var1= '+str(var1)+', id= '+str(id(var1))
def f2(var1):
print 'Within f and BEFORE modification: var1= '+str(var1)+', id= '+str(id(var1))
var1 = 1
print 'Within f and AFTER modification: var1= '+str(var1)+', id= '+str(id(var1))
def f3(var1):
print 'Within f and BEFORE modification: var1= '+str(var1)+', id= '+str(id(var1))
var1 = 10
print 'Within f and AFTER modification: var1= '+str(var1)+', id= '+str(id(var1))
var = 5
print '\n f - var1=10:'
print 'BEFORE FUNCTION CALL: var= '+str(var)+', id= '+str(id(var))
f(var)
print 'AFTER FUNCTION: var= '+str(var)+', id= '+str(id(var))
print '\n f2 - var1=1:'
var = [4,3,1,6]
print 'BEFORE FUNCTION CALL: var= '+str(var)+', id= '+str(id(var))
f2(var)
print 'AFTER FUNCTION: var= '+str(var)+', id= '+str(id(var))
print '\n f3 - var1=10 again:'
var = 7
print 'BEFORE FUNCTION CALL: var= '+str(var)+', id= '+str(id(var))
f3(var)
print 'AFTER FUNCTION: var= '+str(var)+', id= '+str(id(var))
print '\n f2 - var1=1 again:'
var='a'
print 'BEFORE FUNCTION CALL: var= '+str(var)+', id= '+str(id(var))
f2(var)
print 'AFTER FUNCTION: var= '+str(var)+', id= '+str(id(var))
输出:
^{pr2}$我知道一个对象的标识在其生存期内是唯一的,并且两个具有非重叠生存期的对象可能具有相同的id()
值。在
从中我了解到,在不同变量的代码执行期间,我可以得到相同的id()
,但是我很惊讶在我的代码中相同的id()
值也与变量值一致。在
我的意思是,对于var1=10
,我总是得到相同的id()
值。赋值var1=1
也有同样的情况,它有自己的id()
值。即使在不同的函数中执行此赋值,也会返回相同的id()
。在
所以我的问题是: Python是否保存了以前的变量、值和标识的记录,即使它们的生命周期已经过期?在
如果在代码中有一个变量赋值与先前过期的变量具有相同的值,那么Python是否会检查内存中先前过期变量的记录,并对相同的内存值优先使用相同的id()
?在
我想了解更多关于id()
值重用和Python程序中内存管理的知识。在
简短回答您的问题-Python缓存范围为[-5256]的整数。在
因此,无论何时执行
var1 = 10
或var1 = 1
,总是从整数缓存中获取相同的对象,这就是为什么即使在函数的不同运行中也会看到相同的id
。在如果对大于或等于257的值进行尝试,可能会看到不同的结果。在
一个非常简单的行为例子-
文档是正确的,但是生存期和对象标识可能会有点混淆。当赋值给一个变量时(无论是普通的还是扩充的)意味着它后面的变量引用赋值右边的对象(可能是另一个对象)。这就是赋值后
id(x)
发生变化的原因。在还请注意,解释器可能会将对对象的引用隐藏在背后,这意味着对象的生存期可能比预期的长(在某些情况下甚至与解释器的生存期一样长),或者比您预期的更早创建。在某些情况下,可以再次访问这些对象。在
例如,一些(目前我认为是-5到+256)整数就在这些对象中(所以在您编写}已经存在)。注意,否则相等的整数不必是相同的(即
x=1
之前,对象{x==y
并不意味着x is y
),这意味着存在冗余对象。在另一个例子是internetd strings,通常情况下,解释器为了提高效率而对字符串进行内接(所以在编写}已经存在,因为这是python internes的字符串之一)。在
x="keys"
之前,对象{第三个例子是,对象可以在读取编译后的python代码时创建,这意味着数字对象甚至可以在代码开始执行之前创建。这意味着具有相同值的整型文字和字符串文字将是同一个对象-前提是它们是在同一时间编译的。在
请注意,这些对象是不可变的,因此,如果您碰巧再次获得相同的对象,则不会受到伤害(因为它们是不可变的,因此无论它们是新创建的还是重用的,它们都是相等的)。在
另一个问题是函数会缓存其中的所有常量。在
因此
通过查看函数的代码对象,可以找到与函数关联的缓存常量。在
^{pr2}$元组通常是数字、字符串或元组。因此,正如您总是为
var1
分配一个文本整数,编译器知道这是不能更改的常量值,因此在函数调用之间缓存该整数对象。在我在
f
中使用float的原因是这是唯一一个将缓存float的实例。字符串和整数也可以在其他情况下缓存,例如更新
虽然元组在Python中被认为是不可变的,但在实现级别上,它们只是另一个可变内存。有时,如果Python知道没有其他人可以访问这个tuple,它会对一个tuple进行变异。例如
请参阅定义zip next method的相应行。在
相关问题 更多 >
编程相关推荐