0

I'm trying to learn python syntax and I don't understand why the example below doesn't work. I get this error:

TypeError: __init__() takes 1 positional argument but 2 were given

Code:

class Parent:
    def __init__(self):
        self.lastName = "Mustermann" 
        self.firstName = "Max"
    def get_name(self):
        return self.firstName+" "+self.lastName 
class Child(Parent):
    def __init__(self):
        self.firstName = "Moritz"
        self.lastName=Parent.lastName
p=Parent()
c = Child(p)
print(c.get_name())

I also don't understand why Parent.lastName should work (according to what I read). Parent is a class, so why would it access the lastName of the instance? What I really want is that Child inherits the lastName of Parent, but not the firstName.

4
  • 1
    c = Child(p) => c = Child(). You don't need an instance to inherit from a class Commented Feb 14, 2019 at 22:01
  • 1
    Alternatively, a Child instance has a Parent, rather than being a Parent, in which case Child should not inherit from Parent, but instead Child.__init__ should take an instance of Parent as an argument. Commented Feb 14, 2019 at 22:13
  • Parent.lastName doesn't work - AttributeError: type object 'Parent' has no attribute 'lastName' but it is stopping at your first error. Commented Feb 14, 2019 at 22:23
  • @chepner That would make more sense, but I was trying to learn inheritance, thats why I constructed it this way. But I could invent better names for that example, because maybe thats what unconsciously tricked my brain into wrinting Child(p). Commented Feb 14, 2019 at 22:26

2 Answers 2

3

c = Child(p) is an error: the constructor doesn't take any argument except the self implicit one.

You don't need to copy lastName as Child inherits from Parent. But since you defined __init__ in Child you have to call Parent __init__ method as well for that (else parent constructor isn't called):

class Parent:
    def __init__(self):
        self.lastName = "Mustermann"
        self.firstName = "Max"
    def get_name(self):
        return self.firstName+" "+self.lastName
class Child(Parent):
    def __init__(self):
        Parent.__init__(self)
        self.firstName = "Moritz"

p=Parent()
c = Child()
print(c.get_name())

prints:

Moritz Mustermann

To call the parent __init__ method we used

Parent.__init__(self)

we could also have used super like this:

super(Child,self).__init__()

which amounts to the same thing here (single inheritance), so even like:

super().__init__()
Sign up to request clarification or add additional context in comments.

4 Comments

should'nt that be a super(Parent,self).__init__() call?
it doesn't work because it's super(Child,self).__init__() :)
Just plain super().__init__() would work (in Py3).
it does. Adopting that syntax from now. Worked too much with old 2.x python versions so super wasn't my friend...
1

A child isn't (necessarily) a parent, it has a parent. Also, the names shouldn't be hard-coded in the __init__ method, but passed as arguments. Not every instance of Child or Person will have the same names (although in this simple example, a child will share its parent's last name).

(I changed Parent to Person since there's nothing particularly parent-like about the Parent class. A Child still has a Person as a parent, though.)

class Person:
    def __init__(self, firstName, lastName):
        self.lastName = firstName
        self.firstName = lastName

    def get_name(self):
        return self.firstName+" "+self.lastName 


class Child(Person):
    def __init__(self, firstName, parent):
        super().__init__(firstName, parent.lastName)
        self.parent = parent

p = Person("Max", "Mustermann")
c = Child("Moritz", p)
print(c.get_name())

4 Comments

c.get_name() will no longer work... perhaps Parent and Child should inherit from Person and define get_name() in Person. And it does usually take 2 to tango :)
Yeah, I never bothered looking at get_name :)
(I may also have taken the Child/Parent names too literally, but at least now the answer demonstrates both inheritance and composition.)
@chepner You have taken them too literally, but your answer is still useful. I renamed Parent and Child into Person and Programmer. That makes my example much less confusing, which shows how important good variable names are. ;)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.