-4

With below code I am trying to find the oldest of the 3 cats. When I try to call the method 'cat_age' of class 'Cat' in the print statement it gives the below error:

NameError: name 'cat_age' is not defined

Below is the code:

class Cat:
  def __init__(self, name, age):
    self.name=name
    self.age=age
  def cat_age(self, *args):
    return max(args)


cat1=Cat('Pinky', 10)
cat2=Cat('Tinky', 11)
cat3=Cat('Sinky', 13)



print(f'The oldest cat is {cat_age(cat1.age, cat2.age, cat3.age)} years old')

Please help me understand what is going on.

  • 1
    Why do you need `cat_age`? It is just a wrapper over `max`? – Tomerikoo Mar 20 '23 at 10:15
  • "When I try to call the method 'cat_age' of class 'Cat'" - no, you call just a function `cat_age`. There's no mention of `Cat` anywhere nearby. – Sergio Tulentsev Mar 20 '23 at 10:16
  • 1
    An instance method is called on an ***instance***. i.e. `cat1.some_method()`. But you are calling a method as if it was a function in the global scope. Anyway `cat_age` doesn't make sense as an instance method. ***Maybe*** it could be a `@classmethod` receiving an arbitrary number of instances of its class – Tomerikoo Mar 20 '23 at 10:17
  • 1
    Could be: `print( f'The oldest cat is {cat1.cat_age(cat1.age, cat2.age, cat3.age)} years old' )` – Maurice Meyer Mar 20 '23 at 10:18

1 Answers1

2

When you define a function inside a class, that defines an instance method. These are functions that are called on a specific instance of the class and get it (the instance) as an argument. You call those as instance.method().

So when you def cat_age(self, *args): inside the class - this is an instance method. But then you call it as cat_age(...) and such name does not exist in the global scope.

To be frank, it doesn't make much sense to define such method as it is just a wrapper on the max built-in function and it is a lot more readable to just use.... max.

But if you really wanted, you could define a @staticmethod that takes an arbitrary number of instances:

class Cat:
    def __init__(self, name, age):
        self.name = name
        self.age = age

    @staticmethod
    def max_age(*args):
        return max(arg.age for arg in args)

cat1 = Cat('Pinky', 10)
cat2 = Cat('Tinky', 11)
cat3 = Cat('Sinky', 13)

print(f'The oldest cat is {Cat.max_age(cat1, cat2, cat3)} years old')

Will print:

The oldest cat is 13 years old
Tomerikoo
  • 18,379
  • 16
  • 47
  • 61