Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/341.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
python中的Lambda函数比较_Python_Lambda_Python Internals - Fatal编程技术网

python中的Lambda函数比较

python中的Lambda函数比较,python,lambda,python-internals,Python,Lambda,Python Internals,在python中,无法直接比较lambda表达式创建的函数: >>> (lambda x: x+2) == (lambda x: x+2) False 我做了一个例行程序来分解分解 import sys import dis import hashlib import contextlib def get_lambda_hash(l, hasher=lambda x: hashlib.sha256(x).hexdigest()): @contextlib.cont

在python中,无法直接比较lambda表达式创建的函数:

>>> (lambda x: x+2) == (lambda x: x+2)
False
我做了一个例行程序来分解分解

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])
用法是:

>>>> 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

这个问题还有更优雅的解决方案吗?

如果你坚持要执行这种疯狂的行为,请比较每种行为的字节码和常量

>>> 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

如果你需要比较,也许lambda不是这个工作的工具?表达式应该是语法上的还是语义上的相等?后者不能完成。@ JrrSape认为你有一个库来读取带有行和列的长文件到内存中。您可以指定要选择的列,也可以指定lambdas在选择时进行一些操作,例如选择两列之和。现在,您想做缓存,关键是选择哪些列(和lambda!)。是的,但不清楚为什么会出现这种要求,这似乎表明在设计上有更广泛改进的潜力。这可能是一个XY问题;参见例如@ CopSoSt语法,这可能不够好。例如,对于<代码> DEF f(x):返回lambda y:x+y它会考虑<代码> f(1)和<代码> f(2)< /C>是相同的函数。如果在lambda中使用的数据改变,也不好,如在<代码> lambda x:Apple Digt[x] < /COD>字典<代码>某个Distt < /C> >更改。