user2175034
user2175034

Reputation: 93

Silly Example But Type Errors?

class Cat(object):
    def __init__(self,run,fast):
        self.run=run
        self.fast=fast

    def skip(self,to,store):
        return 'Cat'

class Dog(Cat):
    def __init_(self,run, fast,tongue):
        Cat.__init__(self,run,fast)
        self.tongue=tongue

    def skip(self,to,store,happier):
        return 'Doggy'
class Parent(object):
    def __init__(self,velocity):
        self.velocity=velocity

"""
velocity is a list of speeds or something. But it can 
be from dogs or cats. Fast is a single number
"""
class Owner(Parent):
    def __init__(self,smile):
        Parent.__init__(self,velocity)
        self.smile=smile
        self.jumper=[]

    def update(self):
        # velocity is a list of instances of cats and dog
        for number in self.velocity:
            if isinstance(number,Dog):
                number.skip(to,store,happier)
                self.jumper.append(number)
            if isinstance(number,Cat):
                 number.skip(to,store)
                self.jumper.append(number)

The problem that keeps arises is say i go to that first if statement in the if instance update method, it keeps giving me a type error, where it is saying I only need to arguments for skip and not three. Yet I know because it is going in the block the instance I must have is dog, which needs three arguments. Why is this type error keep arising?

Upvotes: 2

Views: 89

Answers (2)

jwodder
jwodder

Reputation: 57610

You haven't shown us the actual error message you're getting, but I'm going to assume that you're misinterpreting it and it's actually saying that you're passing only two arguments to a method that expects three. Specifically, I expect that the problem is not with this code block:

if isinstance(number,Dog):
    number.skip(to,store,happier)
    self.jumper.append(number)

But with the one right after it:

if isinstance(number,Cat):
    number.skip(to,store)
    self.jumper.append(number)

Because Dog is a subclass of Cat, any instance of Dog is also an instance of Cat. Thus, if number is a Dog, the first block of code will run successfully, and then, because you're using if instead of elif, the second block of code will try to execute, and Python will try to call .skip(to, store) on the Dog, which doesn't work, because Dog's skip expects three arguments.

It's not clear from this contrived example what you want to do in the first place, but I suspect that the best solution to your problem is to simply change the second if to an elif so that Dogs won't be treated as non-Dog Cats.

Upvotes: 3

John Zwinck
John Zwinck

Reputation: 249502

What you've got here is a derived class which overrides a base class method with a different signature (formal parameter list). You can read some about this here:

Python: Can subclasses overload inherited methods?

Perhaps you should not use the same method name in both classes, since the two methods aren't really interchangeable. Or you could make them interchangeable by taking extra arguments as *args or **kwargs, not needing those extra arguments in the base class, but using them in the derived. Something like this:

class Cat(object):
    def skip(self,to,store,*args):
        return 'Cat'

class Dog(Cat):
    def skip(self,to,store,happier):
        return 'Doggy'

Now either class can have its method called with three arguments (plus self).

Upvotes: 0

Related Questions