4

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


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

我该怎么做?我知道我可能会覆盖eqne如果 fa、fb、fc 是某个类的实例。但是这里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 = {}

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

4

3 回答 3

6

如果你把你的函数变成了一些覆盖__call__()以及比较运算符的类的实例,那么很容易实现你想要的语义。

于 2012-05-29T07:23:49.693 回答
2

It is not possible to override the __eq__ implementation for functions (tested with 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'
于 2012-05-29T13:14:11.237 回答
0

我不认为这是可能的。

但是覆盖__call__对我来说似乎是一个不错的解决方案。

于 2012-05-29T08:01:48.497 回答