Note that there are some explanatory texts on larger screens.

plurals
  1. POImplementing __neg__ in a generic way for all subclasses in Python
    primarykey
    data
    text
    <p>I apologize in advance for the rather long question.</p> <p>I'm implementing callable objects and would like them to behave somewhat like (mathematical) functions. I have a base class whose <code>__call__</code> method raises <code>NotImplementedError</code> so users must subclass to define <code>__call__</code>. My question is: how can I define the special method <code>__neg__</code> in the <em>base class</em> so subclasses immediately have the expected behavior without having the implement <code>__neg__</code> in each subclass? My sense of the expected behavior is that if <code>f</code> is an instance of (a subclass of) the base class with a properly defined <code>__call__</code>, then <code>-f</code> should be an instance of the same class as <code>f</code>, possessing all the same attributes as <code>f</code>, except for <code>__call__</code>, which should return the negative of <code>f</code>'s <code>__call__</code>.</p> <p>Here's an example of what I mean:</p> <pre><code>class Base(object): def __call__(self, *args, **kwargs): raise NotImplementedError, 'Please subclass' def __neg__(self): def call(*args, **kwargs): return -self(*args, **kwargs) mBase = type('mBase', (Base,), {'__call__': call}) return mBase() class One(Base): def __init__(self data): self.data = data def __call__(self, *args, **kwargs): return 1 </code></pre> <p>This has the expected behavior:</p> <pre><code>one = One() print one() # Prints 1 minus_one = -one print minus_one() # Prints -1 </code></pre> <p>though it's not exactly what I'd like since <code>minus_one</code> is not an instance of the same class as <code>one</code> (but I could live with that).</p> <p>Now I'd like the new instance <code>minus_one</code> to inherit all attributes and methods of <code>one</code>; only the <code>__call__</code> method should change. So I could change <code>__neg__</code> to</p> <pre><code> def __neg__(self): def call(*args, **kwargs): return -self(*args, **kwargs) mBase = type('mBase', (Base,), {'__call__': call}) new = mBase() for n, v in inspect.getmembers(self): if n != '__call__': setattr(new, n, v) return new </code></pre> <p>This seems to work. My question is: are there cons to this strategy? Implementing a generic <code>__neg__</code> must be a standard exercise but I couldn't find anything on it on the web. Are there recommended alternatives?</p> <p>Thanks in advance for any comments.</p>
    singulars
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload