views:

323

answers:

4

I don't think so, but I thought I'd ask just in case. For example, for use in a class that encapsulates an int:

i = IntContainer(3)
i + 5

And I'm not just interested in this int example, I was looking for something clean and general, not overriding every int and string method.

Thanks, sunqiang. That's just what I wanted. I didn't realize you could subclass these immutable types (coming from C++).

class IntContainer(int):
    def __init__(self,i):
        #do stuff here
        self.f = 4

    def MultiplyBy4(self):
        #some member function
        self *= self.f
        return self

print 3+IntContainer(3).MultiplyBy4()
+3  A: 

Is this what you need?

In [1]: class IntContainer(object):
   ...:     def __init__(self, val):
   ...:         self.val = val
   ...:     def __add__(self, val):
   ...:         return self.val + val
   ...:     def __radd__(self, val):
   ...:         return self.val + val
   ...:
   ...:

In [2]: i = IntContainer(3)

In [3]: i + 5
Out[3]: 8

In [4]:
del-boy
Not really. I was looking for something like the C++ conversion operator, that intelligently replaces the container object with whatever it's containing in expressions.
Alex
This will fail for "5 + i", I believe.
ars
ars, you are right, I saw your answer and I am missing __radd__ ... I guess now it's ok after I changed my answer...
del-boy
Yup, that should work. :)
ars
+8  A: 

This should do what you need:

class IntContainer(object):
    def __init__(self, x):
        self.x = x

    def __add__(self, other):
        # do some type checking on other
        return self.x + other

    def __radd__(self, other):
        # do some type checking on other
        return self.x + other

Output:

In [6]: IntContainer(3) + 6
Out[6]: 9

In [7]: 6 + IntContainer(3)
Out[7]: 9

For more information search for "radd" in the following docs:

You'll find other such methods for "right addition", "right subtraction", etc.

Here's another link covering the same operators:

By the way, Python does have casting operators:

But, they won't accomplish what you need in your example (basically because methods don't have any type annotation for parameters, so there's no good way to cast implicitly). So you can do this:

class IntContainer2(object):
    def __init__(self, x):
        self.x = x

    def __int__(self):
        return self.x


ic = IntContainer2(3)
print int(ic) + 6
print 6 + int(ic)

But this will fail:

print ic + 6  # error: no implicit coercion
ars
+3  A: 

You won't get conversion operators like in C++ because Python does not have this kind of strong static type system. The only automatic conversion operators are those which handle default numeric values (int/float); they are predefined in the language and cannot be changed.

Type "conversion" is usually done by constructors/factories. You can then overload standard methods like __add__ to make it work more like other classes.

liori
+1  A: 

sometimes maybe just subclass from int directly is enough. then __add__ and __radd__ need not costuming.

class IntContainer(int):
    pass
i = IntContainer(3)
print i + 5 # 8 
print 4 + i # 7

class StrContainer(str):
    pass
s = StrContainer(3)
print s + '5' # 35
print '4' + s # 43
sunqiang