Generic binary operation in a class definition?
<p>I am writing a tiny linear algebra module in Python 3, and there are a number of binary operators to define. Since each definition of a binary operator is essentially the same with only the operator itself changed, I would like to save some work by writing a generic binary operator definition only once.</p>

<p>For example:</p>

<pre><code>class Vector(tuple):
    def __new__(self, x):
        super().__new__(x)

    # Binary operators

    def __add__(self, xs):
        try:
            return Vector(a + x for a, x in zip(self, xs)))
        except:
            return Vector(a + x for a in self)

    def __and__(self, xs):
        try:
            return Vector(a &amp; x for a, x in zip(self, xs))
        except:
            return Vector(a &amp; x for a in self)

    ... # mul, div, or, sub, and all other binary operations
</code></pre>

<p>The binary operators above all have the same form. Only the operator is changed. I wonder if I could instead write all operators at once, something like this:</p>

<pre><code>def __bop__(self, xs):
    bop = get_bop_somehow()
    try:
        return Vector(bop(a, x) for a, x in zip(self, xs)))
    except:
        return Vector(bop(a, x) for a in self)
</code></pre>

<p>I've heard that Python can do magical things with the <code>__getattr__</code> method, which I tried to use to extract the name of the operator like so:</p>

<pre><code>def __getattr__(self, name):
    print('Method name:', name.strip('_'))
</code></pre>

<p>But, unfortunately, this only works when called using the full method name, not when an operator is used. How can I write a one-size-fits-all binary operator definition?</p>

<p>You can do this with the <code>operator</code> module, which gives you functional versions of the operators. For example, <code>operator.and_(a, b)</code> is the same as <code>a &amp; b</code>.</p>

<p>So <code>return Vector(a + x for a in self)</code> becomes <code>return Vector(op(a, x) for a in self)</code> and you can parameterize <code>op</code>. You still need to define all of the magic methods, but they can be simple pass-throughs.</p>

python class