Parham
Parham

Reputation: 3472

Function polymorphism in Python

I've been looking around for the best way of doing this but I haven't really found anything completely convincing.

I am writing a system where you have User objects and a collection that manages those Users. Each User has a name and I want to specify a function in the manager that can either take the name of the User or the User object itself.

class UserManager: 
  def remove_user(self,user_or_username):
    #If user_or_username is a string
    remote.remove(user_or_username)
    #If user_or_username is a User object
    remote.remove(user_or_username.name)

Is there any nifty way of doing this or is usage of isinstance the way to go?

Upvotes: 8

Views: 12517

Answers (4)

glglgl
glglgl

Reputation: 91017

A solution like mgilson's, but slightly different:

def remove_user(self,user_or_username):
    try:
        #If user_or_username is a User object
        username = user_or_username.name
    except AttributeError:   #Oops -- didn't works.  ask forgiveness ;-)
        #If user_or_username is a string
        username = user_or_username
    remote.remove(username)

Why? Because this way, AttributeErrors in remove() are not suppressed.

It might be irrelevant, but I prefer concentrating exception handling to those places I really inted to have them.

Upvotes: 5

Mp0int
Mp0int

Reputation: 18727

using isinstance is a good approach... There is one more approach for this solution

if hasattr(user_or_username, 'name'):
    # this object has <name> attribute
    remote.remove(user_or_username.name)
else:
    remote.remove(user_or_username)

Upvotes: 3

robert
robert

Reputation: 34398

I would use isinstance, but this also works:

def remove_user(self, user):
   if hasattr(user, "name"):
      self.remove(user.name)
   else:
      self.remove(user)

Upvotes: 2

mgilson
mgilson

Reputation: 309821

Sometimes python people like to say "it's better to ask forgiveness than permission"...

  def remove_user(self,user_or_username):
    try:
        #If user_or_username is a User object
        remote.remove(user_or_username.name)
    except AttributeError:   #Oops -- didn't works.  ask forgiveness ;-)
        #If user_or_username is a string
        remote.remove(user_or_username)

But I say it's just a matter of preference really. You could also use isinstance just as easily if you know you're only going to be getting strings, or User instances.

Upvotes: 2

Related Questions