Re: Automatically generating arithmetic operations for a subclass

2009-04-15 Thread Steven D'Aprano
On Tue, 14 Apr 2009 19:24:56 +0200, Sebastian Wiesner wrote:

 Is there a trick or Pythonic idiom to make arithmetic operations on a
 class return the same type, without having to manually specify each
 method? I'm using Python 2.5, so anything related to ABCs are not an
 option.
 
 Does anyone have any suggestions?
 
 Metaclasses can be used for this purpuse, see the example for a Roman
 number type [1]
 
 [1] http://paste.pocoo.org/show/97258/


That's an interesting solution. I like it.


Thanks to all who responded, I see that there's no best practice to get 
what I want, so I'll do some experimentation.



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


Re: Automatically generating arithmetic operations for a subclass

2009-04-14 Thread Arnaud Delobelle
Arnaud Delobelle arno...@googlemail.com writes:

 binops = ['add', 'sub', 'mul', 'div', 'radd', 'rsub'] # etc
 unops = ['neg', 'abs', invert'] # etc

Oops.  There's a missing quote above. It should have been, of course:

unops = ['neg', 'abs', 'invert'] # etc

  
 binop_meth = 
 def __%s__(self, other):
 return type(self)(int.__%s__(self, other))
 

 unop_meth = 
 def __%s__(self):
 return type(self)(int.__%s__(self))
 

 class MyInt(int):
   for op in binops:
   exec binop_meth % (op, op)
   for op in unops:
   exec unop_meth % (op, op)
   del op

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


Re: Automatically generating arithmetic operations for a subclass

2009-04-14 Thread Paul McGuire
On Apr 14, 4:09 am, Steven D'Aprano
ste...@remove.this.cybersource.com.au wrote:
 I have a subclass of int where I want all the standard arithmetic
 operators to return my subclass, but with no other differences:

 class MyInt(int):
     def __add__(self, other):
         return self.__class__(super(MyInt, self).__add__(other))
     # and so on for __mul__, __sub__, etc.

 My quick-and-dirty count of the __magic__ methods that need to be over-
 ridden comes to about 30. That's a fair chunk of unexciting boilerplate.


Something like this maybe?

def takesOneArg(fn):
try:
fn(1)
except TypeError:
return False
else:
return True

class MyInt(int): pass

template = MyInt.__%s__ = lambda self, other: self.__class__(super
(MyInt, self).__%s__(other))
fns = [fn for fn in dir(int) if fn.startswith('__') and takesOneArg
(getattr(1,fn))]
print fns
for fn in fns:
exec(template % (fn,fn))


Little harm in this usage of exec, since it is your own code that you
are running.

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


Re: Automatically generating arithmetic operations for a subclass

2009-04-14 Thread Gerard Flanagan

Steven D'Aprano wrote:
I have a subclass of int where I want all the standard arithmetic 
operators to return my subclass, but with no other differences:


class MyInt(int):
def __add__(self, other):
return self.__class__(super(MyInt, self).__add__(other))
# and so on for __mul__, __sub__, etc.




Just an idea:


def myint(meth):
def mymeth(*args):
return MyInt(meth(*args))
return mymeth

class MyIntMeta(type):

method_names = 'add sub mul neg'.split()

def __new__(cls, name, bases, attrs):
t = type.__new__(cls, name, bases, attrs)
for name in MyIntMeta.method_names:
name = '__%s__' % name
meth = getattr(t, name)
setattr(t, name, myint(meth))
return t


class MyInt(int):
__metaclass__ = MyIntMeta

a = MyInt(3)
b = MyInt(3000)

print a
print b
c = a + b
print c
assert isinstance(c, MyInt)
d = c * MyInt(4)
print d
e = c * 6 * a * b
print e
assert isinstance(e, MyInt)

x = -e
print x
assert isinstance(x, MyInt)






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


Re: Automatically generating arithmetic operations for a subclass

2009-04-14 Thread andrew cooke
Arnaud Delobelle wrote:
 I do this:

 binops = ['add', 'sub', 'mul', 'div', 'radd', 'rsub'] # etc
 unops = ['neg', 'abs', invert'] # etc

 binop_meth = 
 def __%s__(self, other):
 return type(self)(int.__%s__(self, other))
 

 unop_meth = 
 def __%s__(self):
 return type(self)(int.__%s__(self))
 

 class MyInt(int):
   for op in binops:
   exec binop_meth % (op, op)
   for op in unops:
   exec unop_meth % (op, op)
   del op

what's the del for?

curious,
andrew


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


Re: Automatically generating arithmetic operations for a subclass

2009-04-14 Thread Diez B. Roggisch
andrew cooke wrote:

 Arnaud Delobelle wrote:
 I do this:

 binops = ['add', 'sub', 'mul', 'div', 'radd', 'rsub'] # etc
 unops = ['neg', 'abs', invert'] # etc

 binop_meth = 
 def __%s__(self, other):
 return type(self)(int.__%s__(self, other))
 

 unop_meth = 
 def __%s__(self):
 return type(self)(int.__%s__(self))
 

 class MyInt(int):
   for op in binops:
   exec binop_meth % (op, op)
   for op in unops:
   exec unop_meth % (op, op)
   del op
 
 what's the del for?

To not pollute the namespace of MyInt - otherwise, you could do

MyInt(10).op


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


Re: Automatically generating arithmetic operations for a subclass

2009-04-14 Thread Arnaud Delobelle
Steven D'Aprano ste...@remove.this.cybersource.com.au writes:

 I have a subclass of int where I want all the standard arithmetic 
 operators to return my subclass, but with no other differences:

 class MyInt(int):
 def __add__(self, other):
 return self.__class__(super(MyInt, self).__add__(other))
 # and so on for __mul__, __sub__, etc.


 My quick-and-dirty count of the __magic__ methods that need to be over-
 ridden comes to about 30. That's a fair chunk of unexciting boilerplate.

 Is there a trick or Pythonic idiom to make arithmetic operations on a 
 class return the same type, without having to manually specify each 
 method? I'm using Python 2.5, so anything related to ABCs are not an 
 option.

 Does anyone have any suggestions?

I do this:

binops = ['add', 'sub', 'mul', 'div', 'radd', 'rsub'] # etc
unops = ['neg', 'abs', invert'] # etc
 
binop_meth = 
def __%s__(self, other):
return type(self)(int.__%s__(self, other))


unop_meth = 
def __%s__(self):
return type(self)(int.__%s__(self))


class MyInt(int):
  for op in binops:
  exec binop_meth % (op, op)
  for op in unops:
  exec unop_meth % (op, op)
  del op

HTH

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


Re: Automatically generating arithmetic operations for a subclass

2009-04-14 Thread Arnaud Delobelle
andrew cooke and...@acooke.org writes:

 Arnaud Delobelle wrote:
 I do this:

 binops = ['add', 'sub', 'mul', 'div', 'radd', 'rsub'] # etc
 unops = ['neg', 'abs', invert'] # etc

 binop_meth = 
 def __%s__(self, other):
 return type(self)(int.__%s__(self, other))
 

 unop_meth = 
 def __%s__(self):
 return type(self)(int.__%s__(self))
 

 class MyInt(int):
   for op in binops:
   exec binop_meth % (op, op)
   for op in unops:
   exec unop_meth % (op, op)
   del op

 what's the del for?

Without it, 'op' would end up as a class attribute.

 curious,
 andrew

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


Re: Automatically generating arithmetic operations for a subclass

2009-04-14 Thread andrew cooke
Arnaud Delobelle wrote:
 andrew cooke and...@acooke.org writes:
 Arnaud Delobelle wrote:
 class MyInt(int):
   for op in binops:
   exec binop_meth % (op, op)
   for op in unops:
   exec unop_meth % (op, op)
   del op

 what's the del for?

 Without it, 'op' would end up as a class attribute.

ah!  ok, that makes sense, i guess.  thanks.

(i just tried it out and you're right, of course, but also if binops and
unops are empty you get an error, although i guess that's no an issue
here).

andrew


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


Re: Automatically generating arithmetic operations for a subclass

2009-04-14 Thread Sebastian Wiesner
Steven D'Aprano – Dienstag, 14. April 2009 11:09

 I have a subclass of int where I want all the standard arithmetic
 operators to return my subclass, but with no other differences:
 
 class MyInt(int):
 def __add__(self, other):
 return self.__class__(super(MyInt, self).__add__(other))
 # and so on for __mul__, __sub__, etc.
 
 
 My quick-and-dirty count of the __magic__ methods that need to be over-
 ridden comes to about 30. That's a fair chunk of unexciting boilerplate.
 
 Is there a trick or Pythonic idiom to make arithmetic operations on a
 class return the same type, without having to manually specify each
 method? I'm using Python 2.5, so anything related to ABCs are not an
 option.
 
 Does anyone have any suggestions?

Metaclasses can be used for this purpuse, see the example for a Roman number 
type [1]

[1] http://paste.pocoo.org/show/97258/

-- 
Freedom is always the freedom of dissenters.
  (Rosa Luxemburg)

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


Re: Automatically generating arithmetic operations for a subclass

2009-04-14 Thread norseman

Steven D'Aprano wrote:
I have a subclass of int where I want all the standard arithmetic 
operators to return my subclass, but with no other differences:


class MyInt(int):
def __add__(self, other):
return self.__class__(super(MyInt, self).__add__(other))
# and so on for __mul__, __sub__, etc.


My quick-and-dirty count of the __magic__ methods that need to be over-
ridden comes to about 30. That's a fair chunk of unexciting boilerplate.

Is there a trick or Pythonic idiom to make arithmetic operations on a 
class return the same type, without having to manually specify each 
method? I'm using Python 2.5, so anything related to ABCs are not an 
option.


Does anyone have any suggestions?




==
Have you thought about making a generator?
The boiler plate is above. Change the necessary parts to VARS and place 
in a loop to write them out. Input file would have the 30 +/- lines to 
be substituted.

  ---
zparts contents:
MyInt, __add__, other
MyMul, __mul__, other
.
.
  ---
zgen contents:
while read ztyp,zop,zother
do
   print (line one..
   print (line two..
   print return self.__class__(super($ztyp, self).zop(zother))
   .
   .
done
 ---

(syntax not necessarily correct, but you get the idea)
Run redirected to lib or program source.



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