在python中测试两个函数的相等性

时间:2012-05-29 07:21:05

标签: python function metaprogramming equality

我想让两个函数彼此相等,如下所示:


def fn_maker(fn_signature):
  def _fn():
    pass
  _fn.signature = fn_signature
  return _fn

# test equality of two function instances based on the equality of their signature values
>>> fa = fn_maker(1)
>>> fb = fn_maker(1)
>>> fc = fn_maker(2)
>>> fa == fb # should be True, same signature values
True
>>> fa == fc # should be False, different signature values
False

我该怎么办?我知道如果fa,fb,fc是某个类的实例,我可能会覆盖eqne。但是这里 eq 不在dir(fa)中并且添加它列表不起作用。 我想出了一些解决方法,比如使用缓存,例如


def fn_maker(fn_signature):
  if fn_signature in fn_maker.cache:
    return fn_maker.cache[fn_signature]
  def _fn():
    pass
  _fn.signature = fn_signature
  fn_maker.cache[fn_signature] = _fn
  return _fn
fn_maker.cache = {}

通过这种方式可以保证相同的签名值只有一个函数(有点像单例)。但我真的在寻找一些更整洁的解决方案。

3 个答案:

答案 0 :(得分:6)

如果您将函数转换为覆盖__call__()的某些类的实例以及比较运算符,那么实现所需的语义将非常容易。

答案 1 :(得分:2)

无法覆盖函数的__eq__实现(使用Python 2.7测试)

>>> def f():
...   pass
...
>>> class A(object):
...   pass
...
>>> a = A()
>>> a == f
False
>>> setattr(A, '__eq__', lambda x,y: True)
>>> a == f
True
>>> setattr(f.__class__, '__eq__', lambda x,y: True)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: can't set attributes of built-in/extension type 'function'

答案 2 :(得分:0)

我认为这不可能。

但是覆盖__call__似乎是一个很好的解决方案。