Re: Automatically generating arithmetic operations for a subclass
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
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
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
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
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
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
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
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
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
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
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