为什么setattr对属性和方法的工作方式不同?

Tim*_*mur 6 python

当我设置属性时,getattr结果会id更改为值id.当我设置方法时,getattr结果id不会改变.为什么?

class A (object):
    a = 1
a = 42
print id(getattr(A, 'a'))
print id(a)
setattr(A, 'a', a)
print id(getattr(A, 'a'))
# Got:
#   36159832
#   36160840
#   36160840

class B (object):
    def b(self):
        return 1
b = lambda self: 42
print id(getattr(B, 'b'))
print id(b)
setattr(B, 'b', b)
print id(getattr(B, 'b'))
# Got:
#   140512684858496
#   140512684127608
#   140512684858496
Run Code Online (Sandbox Code Playgroud)

sec*_*ond 3

区别在于方法在 python 中的工作方式

注意

>>> B.b
<unbound method B.<lambda>>
Run Code Online (Sandbox Code Playgroud)

方法实际上是使用描述符构建的

更新“方法”,描述符没有改变

查看描述符内部,我们发现底层函数确实

class B (object):
    def b(self):
        return 1
b = lambda self: 42
print id(getattr(B, 'b'))
print id(b)
setattr(B, 'b', b)
print id(getattr(B, 'b'))
print id(getattr(B, 'b').im_func)  # grab function from the descriptor


4424060752
4440057568
4424060752
4440057568   # here's our new lambda
Run Code Online (Sandbox Code Playgroud)

您还可以看看

B.__dict__['b']
Run Code Online (Sandbox Code Playgroud)

之前和之后