4

次のように、2つの関数を互いに等しくしたいと思います。


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

どうすればいいですか?私はおそらくオーバーライドできることを知ってeqおりne、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 = {}

このようにして、同じシグニチャ値に対して1つの関数のみが存在することが保証されます(シングルトンのようなものです)。しかし、私は本当にいくつかのきちんとした解決策を探しています。

4

3 に答える 3

6

関数を__call__()、比較演算子だけでなくオーバーライドするクラスのインスタンスに変換すると、必要なセマンティクスを非常に簡単に実現できます。

于 2012-05-29T07:23:49.693 に答える
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'
于 2012-05-29T13:14:11.237 に答える
0

それは不可能だと思います。

しかし、オーバーライド__call__は私には良い解決策のようです。

于 2012-05-29T08:01:48.497 に答える