Muhammad Alkarouri wrote:
Hi everyone,

I was having a go at a simple implementation of Maybe in Python when I
stumbled on a case where x.__mul__(y) is defined while x*y is not.

The class defining x is:

class Maybe(object):
    def __init__(self, obj):
        self.o = obj
    def __repr__(self):
        return 'Maybe(%s)' % object.__getattribute__(self, "o")
    def __getattribute__(self, name):
        try:
            o = object.__getattribute__(self, "o")
            r = getattr(o,name)
            if callable(r):
                f = lambda *x:Maybe(r(*x))
                return f
            else:
                return Maybe(r)
        except:
            return Maybe(None)

The code exercising this class is:

x=Maybe(9)
x.__mul__(7)
Maybe(63)
x*7

Traceback (most recent call last):
  File "<pyshell#83>", line 1, in <module>
    x*7
TypeError: unsupported operand type(s) for *: 'Maybe' and 'int'

The product 7*x will execute __mul__, but to catch x*7, you need to define __rmul__ (the 'r' stands for reverse or some such). However, in fact, you have *not* defined __mul__ in your class. Your __getattribute__ is catching __mul__ as an undefined reference, and doing something with it -- not sure what though.

As proof, continue testing: x.__mul__ and x.__rmul__ both return values (lambdas defined within __getattribute__) and neither x*7 or 7*x work.

If you want both x* and 7*x to be defined, try
   def __mul__(self,r):
       ...
   def __rmul__(self,r):
      ....

Or the operation is commutative, perhaps you can get away with reusing __mul__ for both.
   def __mul__(self,r):
       ...
   __rmul__ = __mull__


Gary Herron


The farthest I can go in this is that I presume that __mul__ (as
called by operator *) is supposed to be a bound method while I am
returning a lambda function. Is this correct? And How can I make the
implementation support such operators?

Cheers,

Muhammad Alkarouri

--
http://mail.python.org/mailman/listinfo/python-list

Reply via email to