James Urban
James Urban

Reputation: 350

defining method of class in if statement

I'm trying to create a class that will create objects with different methods based on an input. The point of this is to avoid using an if statement every time the method is called.

Below is the code I thought would work, but isn't working.

class Food:
    def __init__(self,food_type):
        self.food_type = food_type

        if food_type == 'cookie':
            print 'this is a cookie'
            def is_awesome(self):
                print "is awesome"
        else:
            print 'this is not a cookie'
            def is_awesome(self):
                print "not awesome"

Oreo = Food('cookie')
Oreo.is_awesome()

The code doesn't error on the def is_awesome(self) statement, but instead the Oreo.is_awesome() line raises the error:

"AttributeError: Food instance has no attribute is_awesome".

Is there a better way to make objects with different methods? and is there a reason why the method is_awesome isn't callable by 'Oreo.is_awesome'?

Upvotes: 2

Views: 24706

Answers (3)

Gabriel Cia
Gabriel Cia

Reputation: 465

I encountered a similar situation where I wanted different instances of a class to have one of the methods behave differently depending on the init values but still have the same method name, and didn't want to run if/else statements at every call to the method.

The simplest solution I found was to define a setter method that creates a pointer to the wanted behavior, and this setter method is only run once at initialization:

class Food:
    def __init__(self, food_type):
        self.food_type = food_type
        
        self.set_awesomeness()
    
    def is_awesome():
        return 'is awesome'

    def not_awesome():
        return 'not awesome'

    # Point to the wanted behavior
    def set_awesomeness(self):
        if self.food_type == 'cookie':
            self.awesomeness = Food.is_awesome()
        else:
            self.awesomeness = Food.not_awesome()

    def get_awesomeness(self):
        return self.awesomeness
    
cookie = Food('cookie')
cookie.get_awesomeness() # 'is awesome'

donut = Food('donut')
donut.get_awesomeness() # 'not awesome'

Upvotes: 1

dm03514
dm03514

Reputation: 55962

Is there a better way to make objects with different methods?

Yes a way that works :) Polymorphism is a great candidate.

class Food:
  def is_awesome(self):
    print 'not awesome'

class Cookie(Food):
  def is_awesome(self):
    print 'is awesome'

and is there a reason why the method is_awesome isn't callable by 'Oreo.is_awesome'?

Yes, it's not bound to the instance (conventionally called self) in any

Upvotes: 4

Developer
Developer

Reputation: 178

You have to define the method/function is_awesome(self) and then your if's inside it

class Food:
    def __init__(self,food_type):
        self.food_type = food_type

    def is_awesome(self):
         if self.food_type == 'cookie':
            print 'this is a cookie'
            print "is awesome"
         else:
            print 'this is not a cookie not awesome'
            print "not awesome"


Oreo = Food('cookie')
Oreo.is_awesome()

This works, tested!

Upvotes: 2

Related Questions