Reputation: 1564
In python you cannot directly compare functions created by lambda expressions:
>>> (lambda x: x+2) == (lambda x: x+2)
False
I made a routine to hash the disassembly.
import sys
import dis
import hashlib
import contextlib
def get_lambda_hash(l, hasher=lambda x: hashlib.sha256(x).hexdigest()):
@contextlib.contextmanager
def capture():
from cStringIO import StringIO
oldout, olderr = sys.stdout, sys.stderr
try:
out=[StringIO(), StringIO()]
sys.stdout, sys.stderr = out
yield out
finally:
sys.stdout, sys.stderr = oldout, olderr
out[0] = out[0].getvalue()
out[1] = out[1].getvalue()
with capture() as out:
dis.dis(l)
return hasher(out[0])
The usage is:
>>>> get_lambda_hash(lambda x: x+2) == get_lambda_hash(lambda x: x+1)
False
>>>> get_lambda_hash(lambda x: x+2) == get_lambda_hash(lambda x: x+2)
True
Is there any more elegant solution for this problem?
Upvotes: 4
Views: 4052
Reputation: 799310
If you insist on performing this insane bit of insanity, compare the bytecode and constants of each.
>>> import operator
>>> coco = operator.attrgetter('co_code', 'co_consts')
>>> coco((lambda x: x+2).__code__) == coco((lambda x: x+2).__code__)
True
>>> coco((lambda x: x+2).__code__) == coco((lambda x: x+1).__code__)
False
>>> def foo(y):
... return y + 2
...
>>> coco((lambda x: x+2).__code__) == coco(foo.__code__)
True
Upvotes: 6