Steven D'Aprano wrote: > On Fri, 14 Sep 2007 18:19:45 -0700, James Stroud wrote: > >>> How do I subclass int and/or long so that my class also auto-converts >>> only when needed? >>> >> Use __new__. > > The disadvantage of that is that your example code requires me to > duplicate my methods in the long version and the int version. It's easy > enough to work around that (class factory function) but it just seems all > rather untidy...
The __new__ method is where you implement such decisions. There is no "tidier" way for one class "auto-convert" to another class, which is what you asked for (it says so right up there ^). So, if you don't like the answer, don't ask the question. Despite its unseemly appearance because of all the underscores, it is the natural way in python (to do what you have asked and not something which you didn't ask). The way to avoid duplicating methods (which is what you are asking for, no?) while still allowing your classes to maintain their identities is by using mixins: class MyModulatingMixin(object): def modulate(self, sum): if self.modulus is None: return self.__class__(sum) else: return self.__class__(sum % self.modulus) def __add__(self, other): sum = long.__add__(long(self), long(other)) return self.modulate(sum) def __mul__(self, other): sum = long.__mul__(long(self), long(other)) return self.modulate(sum) class MyLong(long): def __new__(cls, v, m=None): obj = long.__new__(cls, v) obj.modulus = m return obj class MyInt(int): def __new__(cls, v, m=None): try: obj = int.__new__(cls, v) obj.modulus = m except OverflowError: obj = MyLong(v, m) return obj for cls in MyLong, MyInt: cls.__bases__ = (MyModulatingMixin,) + cls.__bases__ py> i = MyInt(51) py> j = MyInt(40, 7) py> k = MyLong(2, 13) py> i + j 91 py> j + k 0 py> k + j 3L py> i * k 102 py> type(i * k) <class '__main__.MyInt'> py> k * i 11L py> type(k * i) <class '__main__.MyLong'> James -- http://mail.python.org/mailman/listinfo/python-list