Python:functools.reduce返回函数引用而非哈希结果的问题排查
functools.reduce()返回函数引用而非哈希值的问题排查与解决
问题场景
学习Python时,尝试用functools.reduce()替代for循环,对字符串列表迭代生成SHA256哈希值,但reduce()执行后返回的是自定义函数hash_two_strings的引用,而非预期的哈希字符串。
原始代码
import functools import hashlib def hash_two_strings(a,b): c = a + b h = hashlib.sha256(c.encode()).hexdigest() return h c1 = ['3', 'sha256', 'C=US,O=Entrust', 'CN=review.mysite.com', '1c:08:ea:51', '2/11/2022', '2/11/2023', 'RSA', '2048'] h = hashlib.md5(c1[0].encode()).hexdigest() for i in range(1, len(c1)): s = h+c1[i] h = hashlib.sha256(s.encode()).hexdigest() print (h) h = functools.reduce(lambda a, b: hash_two_strings, c1[1:], hashlib.sha256(c1[0].encode()).hexdigest()) print (h)
错误输出
2b9d651fee9c0ddc75477be6dba8d1d3600551cf2e355e9f4788d3c728d237a3 <function hash_two_strings at 0x000001FF9B6A3E20>
错误原因
你在reduce()中使用的lambda表达式lambda a, b: hash_two_strings没有调用函数,只是返回了函数对象本身。每次reduce迭代时,这个lambda都会把函数引用作为下一轮迭代的累积值a,最终整个reduce执行完毕后,自然返回的就是这个函数对象。
解决方法
有两种简洁的修正方式:
- 让lambda表达式调用
hash_two_strings,传入参数a和b - 直接将
hash_two_strings函数作为第一个参数传给reduce(),无需额外套lambda
修正后的代码
import functools import hashlib def hash_two_strings(a,b): c = a + b h = hashlib.sha256(c.encode()).hexdigest() return h c1 = ['3', 'sha256', 'C=US,O=Entrust', 'CN=review.mysite.com', '1c:08:ea:51', '2/11/2022', '2/11/2023', 'RSA', '2048'] # 原for循环实现(作为对照) h = hashlib.md5(c1[0].encode()).hexdigest() for i in range(1, len(c1)): s = h+c1[i] h = hashlib.sha256(s.encode()).hexdigest() print("for循环结果:", h) # 方法1:修正lambda,调用函数 h = functools.reduce(lambda a, b: hash_two_strings(a, b), c1[1:], hashlib.sha256(c1[0].encode()).hexdigest()) print("修正lambda后的结果:", h) # 方法2:直接传入hash_two_strings函数(更简洁) h = functools.reduce(hash_two_strings, c1[1:], hashlib.sha256(c1[0].encode()).hexdigest()) print("直接传函数的结果:", h)
正确输出
三个print语句都会输出相同的哈希值:
for循环结果: 2b9d651fee9c0ddc75477be6dba8d1d3600551cf2e355e9f4788d3c728d237a3 修正lambda后的结果: 2b9d651fee9c0ddc75477be6dba8d1d3600551cf2e355e9f4788d3c728d237a3 直接传函数的结果: 2b9d651fee9c0ddc75477be6dba8d1d3600551cf2e355e9f4788d3c728d237a3
内容的提问来源于stack exchange,提问作者OldProgrammerLearningNewTricks
相关产品推荐
相关产品推荐

