为什么 python 的 getattr(obj,'method') 和 obj.method 给出不同的结果?括号如何影响?
Why python's getattr(obj,'method') and obj.method give different results? How do brackets affect?
我的程序只计算 sha256 文件哈希,我决定扩展可能的算法数量。所以我开始使用 getattr()
而不是直接调用。并且哈希值发生了变化。
我花了一段时间才弄清楚问题出在哪里,这里是一个简单的字符串示例(不同之处在于 ()
):
>>> import hashlib
>>> text = 'this is nonsence'.encode()
# unique original
>>> hash1 = hashlib.sha256()
>>> hash1.update(text)
>>> print(hash1.hexdigest())
ea85e601f8e91dbdeeb46b507ff108152575c816089c2d0489313b42461aa502
# pathetic parody
>>> hash2 = getattr(hashlib,'sha256')
>>> hash2().update(text)
>>> print(hash2().hexdigest())
e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855
# solution
>>> hash3 = getattr(hashlib,'sha256')()
>>> hash3.update(text)
>>> print(hash3.hexdigest())
ea85e601f8e91dbdeeb46b507ff108152575c816089c2d0489313b42461aa502
谁能解释一下为什么 hash1
不等于 hash2()
而等于 hash3
?
我错过了什么吗?因为对我来说他们看起来一样:
>>> print(hash1)
<sha256 HASH object @ 0x0000027D76700F50>
>>> print(hash2())
<sha256 HASH object @ 0x0000027D76FD7470>
>>> print(hash3)
<sha256 HASH object @ 0x0000027D76D92BF0>
>>> print(type(hash1))
<class '_hashlib.HASH'>
>>>print(type(hash2()))
<class '_hashlib.HASH'>
>>>print(type(hash3))
<class '_hashlib.HASH'>
事实上,getattr(obj, 'method')
和 obj.method
给出了相同的结果,但是在 #2 的情况下,你用错了。
当您调用函数 hashlib.sha256
时,它 returns 一个新的 HASH 对象,这就是您在案例 #1 和 #3 中处理的对象。然而,在 #2 的情况下,hash2
是函数 hashlib.sha256
,而不是 HASH 对象,并且在您稍后调用它时不会改变,意思是:
- 当您执行
hash2().update(text)
时,结果将被丢弃。
- 当您执行
hash2().hexdigest()
时,结果与 hashlib.sha256().hexdigest()
相同,即空哈希。
为了比较,案例 #2 实际上与此相同:
>>> list().append(0) # Create new list object and append 0
>>> list() # Create new list object
[]
我的程序只计算 sha256 文件哈希,我决定扩展可能的算法数量。所以我开始使用 getattr()
而不是直接调用。并且哈希值发生了变化。
我花了一段时间才弄清楚问题出在哪里,这里是一个简单的字符串示例(不同之处在于 ()
):
>>> import hashlib
>>> text = 'this is nonsence'.encode()
# unique original
>>> hash1 = hashlib.sha256()
>>> hash1.update(text)
>>> print(hash1.hexdigest())
ea85e601f8e91dbdeeb46b507ff108152575c816089c2d0489313b42461aa502
# pathetic parody
>>> hash2 = getattr(hashlib,'sha256')
>>> hash2().update(text)
>>> print(hash2().hexdigest())
e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855
# solution
>>> hash3 = getattr(hashlib,'sha256')()
>>> hash3.update(text)
>>> print(hash3.hexdigest())
ea85e601f8e91dbdeeb46b507ff108152575c816089c2d0489313b42461aa502
谁能解释一下为什么 hash1
不等于 hash2()
而等于 hash3
?
我错过了什么吗?因为对我来说他们看起来一样:
>>> print(hash1)
<sha256 HASH object @ 0x0000027D76700F50>
>>> print(hash2())
<sha256 HASH object @ 0x0000027D76FD7470>
>>> print(hash3)
<sha256 HASH object @ 0x0000027D76D92BF0>
>>> print(type(hash1))
<class '_hashlib.HASH'>
>>>print(type(hash2()))
<class '_hashlib.HASH'>
>>>print(type(hash3))
<class '_hashlib.HASH'>
事实上,getattr(obj, 'method')
和 obj.method
给出了相同的结果,但是在 #2 的情况下,你用错了。
当您调用函数 hashlib.sha256
时,它 returns 一个新的 HASH 对象,这就是您在案例 #1 和 #3 中处理的对象。然而,在 #2 的情况下,hash2
是函数 hashlib.sha256
,而不是 HASH 对象,并且在您稍后调用它时不会改变,意思是:
- 当您执行
hash2().update(text)
时,结果将被丢弃。 - 当您执行
hash2().hexdigest()
时,结果与hashlib.sha256().hexdigest()
相同,即空哈希。
为了比较,案例 #2 实际上与此相同:
>>> list().append(0) # Create new list object and append 0
>>> list() # Create new list object
[]