0

I have in my program a class with a member function that should treat certain objects slightly differently than others. In order to do this, it needs to know which object was passed to it, because these objects would have peculiar data pointed to by their data members.

But it seems that referencing the name of the invoking object is impractical and ill advised. I have also considered creating a new function for these exceptional objects, but then how would the next function down on the stack know to call it?

I suppose I could create another data member as a sort of identifier and test for that when running my function; but that seems like a fairly hacky solution. What is the simplest way to do this?

4
  • 2
    I can't be sure but it sounds like you're discrbing double dispatch. Done that way you don't need to know what was passed. You call methods on what was passed. They do the knowing.CommentedJul 14, 2016 at 23:13
  • Okay. I'll look that up.
    – Luca
    CommentedJul 14, 2016 at 23:22
  • What is it that distinguishes one object from another? Do they have different classes? Different attributes?CommentedJul 15, 2016 at 0:01
  • They both have a matrix data member, but some objects will have their data coming from a critically different source that needs to be treated differently.
    – Luca
    CommentedJul 15, 2016 at 0:03

1 Answer 1

5

There's a couple of ways you can do this:

You can use isinstance to determine what the object's class is:

if isinstance(foo, bar): do_something() elif isinstance(foo, baz): do_something_else() else: default_behavior() 

However, this gets unwieldy quickly with a large number of possible classes, and isn't good OOP.

The OOP way would be to use polymorphism - define a base class with a method that returns the data you need, and then create subclasses:

class Polygon: def area(self): raise NotImplementedError class Rectangle(Polygon): def area(self): return self.width * self.height class Circle(Polygon): def area(self): return math.pi * self.radius**2 

Then, in your other method:

area = obj.area() # you don't have to worry about what type the object is anymore! 

A third, arguably more Pythonic way of going about this is to ask for forgiveness, not permission:

try: foo = obj.bar do_something() except AttributeError: # if obj doesn't have a bar attribute, then it must have a baz attribute foo = obj.baz do_something_else() 

However, if you're using OOP, you should stick with the OOP way of doing things - let polymorphism do all the work.

2
  • Yes, it seems that using polymorphism was the best option. I was able to implement that in a clean, organized way.
    – Luca
    CommentedJul 15, 2016 at 16:09
  • @LucaDelSignore Glad to hear it!
    – user200929
    CommentedJul 15, 2016 at 18:16

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.