4

I want to make two functions equal to each other, like this:


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

How should I do it? I know I could probably override eq and ne if fa, fb, fc are instances of some class. But here eq is not in dir(fa) and adding it the list doesnt work. I figured out some workaround like using a cache, e.g.,


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 = {}

By this way there is a guarantee that there is only one function for the same signature value (kinda like a singleton). But I am really looking for some neater solutions.

4
  • Please describe the problem you are trying to solve. There might be an easier approach. Commented May 29, 2012 at 7:34
  • Yes, @ms4py, thank you for pointing that out. There could be easier solutions to the problem I am working on, like using a class instead of a function. But the thing that I really want to learn is how to 'override' == behavior for functions in python, or it is simply impossible. Commented May 29, 2012 at 7:47
  • No, I think there should be a more general solution than comparing functions, no matter how you do it technically. Can you describe why you want to compare them? Commented May 29, 2012 at 12:56
  • And you cannot override __eq__ for functions, see my answer below. Commented May 29, 2012 at 13:14

3 Answers 3

6

If you turned your functions into instances of some class that overrides __call__() as well as the comparison operators, it will be very easy to achieve the semantics you want.

Sign up to request clarification or add additional context in comments.

1 Comment

Yes, thanks for the tip. But I want to know how far I can really go without wrapping it within an object, like what we can do with functions in Ruby.
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'

Comments

0

I don't think it's possible.

But overriding __call__ seems a nice solution to me.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.