天真的尝试失败得很惨:
import hashlib
class fred(hashlib.sha256):
pass
-> TypeError: Error when calling the metaclass bases
cannot create 'builtin_function_or_method' instances
嗯,事实证明hashlib.sha256是可调用的,不是类。尝试一些更有创意的东西也不管用:
^{pr2}$嗯。。。在
那么,我该怎么做呢?在
以下是我想要实现的目标:
class shad_256(sha256):
"""Double SHA - sha256(sha256(data).digest())
Less susceptible to length extension attacks than sha256 alone."""
def digest(self):
return sha256(sha256.digest(self)).digest()
def hexdigest(self):
return sha256(sha256.digest(self)).hexdigest()
基本上,我希望所有的事情都能通过,除了有人调用结果时,我想插入我自己的额外步骤。有没有一种聪明的方法可以用__new__
或某种元类魔术来实现这一点?在
我有一个很满意的解决方案,我把它作为一个答案贴出来了,但我真的很感兴趣,看看是否有人能想出更好的办法。或者在可读性方面花费很少的冗余或者更快(尤其是在调用update
)的同时仍然具有一定的可读性。在
更新:我运行了一些测试:
# test_sha._timehash takes three parameters, the hash object generator to use,
# the number of updates and the size of the updates.
# Built in hashlib.sha256
$ python2.7 -m timeit -n 100 -s 'import test_sha, hashlib' 'test_sha._timehash(hashlib.sha256, 20000, 512)'
100 loops, best of 3: 104 msec per loop
# My wrapper based approach (see my answer)
$ python2.7 -m timeit -n 100 -s 'import test_sha, hashlib' 'test_sha._timehash(test_sha.wrapper_shad_256, 20000, 512)'
100 loops, best of 3: 108 msec per loop
# Glen Maynard's getattr based approach
$ python2.7 -m timeit -n 100 -s 'import test_sha, hashlib' 'test_sha._timehash(test_sha.getattr_shad_256, 20000, 512)'
100 loops, best of 3: 103 msec per loop
所以,我根据格伦的回答得出了这个答案,这就是我给他赏金的原因:
这有点冗长,但是从文档的角度来看,这个类可以很好地工作,并且有一个相对清晰的实现。使用格伦的优化,
update
是尽可能快的。在有一个麻烦,就是
update
函数显示为数据成员,并且没有docstring。我认为效率是可以接受的。在只需使用
__getattr__
使所有未定义自己的属性都回到底层对象:这基本上消除了
^{pr2}$update
调用的开销,但并不完全消除。如果要完全消除它,请将其添加到__init__
(相应地在copy
中):这将消除查找
update
时额外的__getattr__
调用。在这一切都利用了Python成员函数中一个更有用但常常被忽视的属性:函数绑定。记住,您可以这样做:
因为引用成员函数不会返回原始函数,而是返回该函数与对象的绑定。这就是为什么上面的}。在
__getattr__
返回self.sha256.update
时,返回的函数正确地操作self.sha256
,而不是{创建一个新类,从对象派生,创建一个hashlib.sha256在init中定义成员变量,然后定义哈希类所需的方法,并代理到成员变量的相同方法。在
比如:
其他方法也是如此。在
相关问题 更多 >
编程相关推荐