Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <p>Your approach has several downsides. One example is that you copy all members of the original instance to the new instance -- this won't work if your class overrides any special methods other than <code>__call__</code>, since special methods are only looked up in the dictionary of the object's type when called implicitly. Moreover, it copies a lot of stuff that is actually inherited from <code>object</code> and doesn't need to go in the instance's <code>__dict__</code>.</p> <p>An easier approach that satisfies your exact requirements is to make the new type a subclass of the instance's original type. This can be done by defining a local class inside the <code>__neg__()</code> method:</p> <pre><code>def __neg__(self): class Neg(self.__class__): def __call__(self_, *args, **kwargs): return -self(*args, **kwargs) neg = Base.__new__(Neg) neg.__dict__ = self.__dict__.copy() return neg </code></pre> <p>This defines a new class <code>Neg</code> derived from the original function's type and overwrites its <code>__call__()</code> method. It creates an instance of this class using <code>Base</code>'s constructor -- this is to cover the case that <code>self</code>'s class would take constructor arguments. finally we copy everything that is directly stored in the instance <code>self</code> to the new instance.</p> <p>If I were to design the system, I'd take a completely different approach. I'd fix the interface for a function and would only rely on this fixed interface for <em>every</em> function. I wouldn't bother to copy all attributes of an instance to the negated function, but rather do this:</p> <pre><code>class Function(object): def __neg__(self): return NegatedFunction(self) def __add__(self, other): return SumFunction(self, other) class NegatedFunction(Function): def __init__(self, f): self.f = f def __call__(self, *args, **kwargs): return -self.f(*args, **kwargs) class SumFunction(Function): def __init__(self, *funcs): self.funcs = funcs def __call__(self, *args, **kwargs): return sum(f(*args, **kwargs) for f in self.funcs) </code></pre> <p>This approach does not fulfil your requirement that the function returned by <code>__neg__()</code> has all the attributes and methods of the original function, but I think this requirement is rather questionable as far as design is concerned. I think dropping this requirement will give you a much cleaner and more general approach (as demonstrated by including an <code>__add__()</code> operator in the example above).</p>
    singulars
    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.
    1. This table or related slice is empty.
    1. VO
      singulars
      1. This table or related slice is empty.
    2. VO
      singulars
      1. This table or related slice is empty.
    3. VO
      singulars
      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