1

For example in a Python class can I have two different add methods that can detect whether I am adding an object to an integer, or an object to another object, or an object and a string, etc?

DoubleBass
  • 1,143
  • 4
  • 12
  • 29

3 Answers3

2

Take a look at the multipledispatch module.

Here is a rough but simple example of its use. You can see that it can dispatch to different methods depending on the argument types. It can also handle different numbers of arguments.

from multipledispatch import dispatch

class Adder(object):
    @dispatch(object, int)
    def add(o, i):
        print 'add(object, int):'
        return int(o) + i

    @dispatch(object, basestring)
    def add(o, s):
        print 'add(object, string):'
        return str(o) + s

    @dispatch(int, int)
    def pow(a, b):
        print 'pow(int, int):'
        return a**b

    @dispatch(int, int, int)
    def pow(a, b, c):
        print 'pow(int, int, int):'
        return a**b**c

>>> a = Adder()
>>> a.add(1, ' one')
add(object, string):
'1 one'
>>> a.add(100, 1)
add(object, int):
101
>>> a.pow(2, 2)
pow(int, int):
4
>>> a.pow(2, 2, 2)
pow(int, int, int):
16
mhawke
  • 84,695
  • 9
  • 117
  • 138
2

Python objects have special methods. Special methods are just methods that come packaged with a type. For example an int type has an __add__() special method that takes one argument. int.__add__(5) which will add 5 to that int (an actual number is a bad example for an object, but int is an object type which can work for this example). You often see this in code like this:

a = 10 + 5

which is kind of like

a = 10.__add__(5)

Not the best example, I know.

You can create your own class with a method

__add__(self, value)

and in that method you can check against what type value is, usually with isinstance(). If you check for all sorts of types in your __add__() method you are kind of doing polymorphism. Polymorphism like this is typically frowned upon in Python world. Why?

Well if you have a class called Car and an instance of that class called car, what does car = car + 5 mean? And if we add car + 'Sammy drives', what should print(car) print?

If you need to apply data of one type to an object and data of another type to the same object, then usually if is more clear to apply each data type to a specific attribute of that object. Like so:

car.speed = car.speed + 5
car.driver = 'Sammy'

Also I'd recommend getting to know about ducktyping. If you are good at it, checking for object types in your code kind of goes away.

Blacklight Shining
  • 1,468
  • 2
  • 11
  • 28
DevPlayer
  • 5,393
  • 1
  • 25
  • 20
  • `__add__()` does not add to that object; it returns a different object that is the sum of the original and the argument. `__iadd__()` adds to the original for mutable objects (e.g. it will concatenate its argument to a `list`), but as `int` is immutable, it returns a different object. – Blacklight Shining Apr 19 '15 at 14:07
-2

Yes, you can use isinstance to check if an object is of a particular type.

orlp
  • 112,504
  • 36
  • 218
  • 315
  • @DoubleBass `isinstance()` is better for type-checking than `type()`, but given that Python is duck-typed, I would generally try to avoid type-checking at all. – Blacklight Shining Apr 10 '15 at 01:38
  • Can this be used to overload pow()? pow(a,b) versus pow(a,b,c)? They are both pow() but one has two, the other three arguments, but same name __ pow __ – DoubleBass Apr 10 '15 at 01:44
  • @DoubleBass That's a simpler case—you can simply provide a default value for `c`, effectively making it optional. – Blacklight Shining Apr 10 '15 at 02:04
  • 1
    To use `ininstance()` for this purpose is somewhat more complicated than this answer suggests. You might want to look at http://stackoverflow.com/questions/25336481/overloading-or-alternatives-in-python-api-design - a few different strategies are suggested in the answers. – mhawke Apr 10 '15 at 02:06