为什么方法的身份会发生变化?

时间:2014-01-20 01:56:53

标签: python methods

修改

我不会问这个问题我是否会编写一个改编的代码,这会阻碍在使用内存时出现的怪癖(参见user2357112的回答)

使用以下代码,一切正常且易于理解:

from copy import deepcopy

class A(object):
    def f(self):
        pass

d = {}
def N(obj):
    i = id(obj)
    return '  %d  %s' % (i, d.setdefault(i,len(d)))

print 'A.f',N(A.f)

du1 = dict((j,str(j)) for j in xrange(50000))
w = A.f
print 'w  ',N(w)

print 'A.f',N(A.f)

du2 = deepcopy(du1)
x = A.f
print 'x  ',N(x)

print 'A.f',N(A.f)

du3 = deepcopy(du1)
y = A.f
print 'y  ',N(y)

print '------------------------------'
del y
du4 = deepcopy(du1)
print 'A.f',N(A.f)
print 'w  ',N(w)
print 'x  ',N(x)

print 
del x
du5 = deepcopy(du1)
print 'A.f',N(A.f)
du6 = deepcopy(du1)
print 'w  ',N(w)

del w
du7 = deepcopy(du1)
print 'A.f',N(A.f)

结果

A.f   18668040  0
w     18669040  1
A.f   18668080  2
x     18668000  3
A.f   18668760  4
y     18731616  5
------------------------------
A.f   18669120  6
w     18669040  1
x     18668000  3

A.f   18669080  7
w     18669040  1
A.f   18781928  8

此结果显示每次对方法属性进行属性引用时,都会创建一个方法对象,因为Martijn在引用的代码中对其进行了解释,该代码被称为重复我的问题。

原始问题

我无法解释在以下执行过程中会发生什么。

不要过分关注函数N(),我用它来更容易地删除id()返回的身份,因为有时两个对象的身份虽然不同,却非常相似,例如18717912和18717192。

关键在于,方法的身份在某个时刻取决于它以前经历过的绑定,推动认为​​该方法不是同一个对象!
并且逐步删除在连续绑定期间出现的标识符使得该方法的身份恢复其过去的值!!!

这是什么乱七八糟的?

class A(object):
    def f(self):
        pass
a = A()

d = {}
def N(obj):
    i = id(obj)
    return '  %d  %s' % (i, d.setdefault(i,len(d)))

print 'A.f',N(A.f)

w = A.f
print '----w = A.f------'
print 'A.f',N(A.f)
print 'w  ',N(w)

x = A.f
print '----x = A.f------'
print 'A.f',N(A.f)
print 'x  ',N(x)
print 'w  ',N(w)

y = A.f
print '----y = A.f------'
print 'A.f',N(A.f)
print 'y  ',N(y)
print 'x  ',N(x)
print 'w  ',N(w)

z = A.f
print '----z = A.f------'
print 'A.f',N(A.f)
print 'z  ',N(z)
print 'y  ',N(y)
print 'x  ',N(x)
print 'w  ',N(w)

del z
print '\n----del z--------'
print 'A.f',N(A.f)
print 'y  ',N(y)
print 'x  ',N(x)
print 'w  ',N(w)

del x
print '----del x--------'
print 'A.f',N(A.f)
print 'y  ',N(y)
print 'w  ',N(w)

del w
print '----del w---------'
print 'A.f',N(A.f)
print 'y  ',N(y)

del y
print '----del y---------'
print 'A.f',N(A.f)

结果

A.f   18668040  0
----w = A.f------
A.f   18668760  1
w     18668040  0
----x = A.f------
A.f   18732336  2
x     18668760  1
w     18668040  0
----y = A.f------
A.f   18669120  3
y     18732336  2
x     18668760  1
w     18668040  0
----z = A.f------
A.f   18732496  4
z     18669120  3
y     18732336  2
x     18668760  1
w     18668040  0

----del z--------
A.f   18669120  3
y     18732336  2
x     18668760  1
w     18668040  0
----del x--------
A.f   18668760  1
y     18732336  2
w     18668040  0
----del w---------
A.f   18668040  0
y     18732336  2
----del y---------
A.f   18732336  2

1 个答案:

答案 0 :(得分:4)

Python不保留规范方法对象。每次访问方法时,都会获得一个新创建的方法对象:

>>> OrderedDict.update is OrderedDict.update
False

每次打印A.f的ID时,都是新的A.f对象。删除旧对象时重用旧ID值的事实是分配器和垃圾检测器的怪癖;最近发布的对象的存储经常用于表示新创建的对象。