3

To begin with, I know there is a right way to implement inheritance like this:

class Parent():
    def __init__(self, last_name, eye_color):
        self.last_name = last_name
        self.eye_color = eye_color

class Child(Parent):
    def __init__(self, last_name, eye_color, number_of_toys):
        Parent.__init__(self, last_name, eye_color)
        self.number_of_toys = number_of_toys

miley_cyrus = Child("Cyrus", "Blue", 5)
print(miley_cyrus.last_name)
print(miley_cyrus.number_of_toys)

When I run the piece of code, there is the result that

Cyrus
5

However when I change the 7th line into :

self = Parent(last_name, eye_color)

and the the code has become:

class Parent():
    def __init__(self, last_name, eye_color):
        self.last_name = last_name
        self.eye_color = eye_color

class Child(Parent):
    def __init__(self, last_name, eye_color, number_of_toys):
        self = Parent(last_name, eye_color)
        self.number_of_toys = number_of_toys

miley_cyrus = Child("Cyrus", "Blue", 5)
print(miley_cyrus.last_name)
print(miley_cyrus.number_of_toys)

, I run the piece of code, there is an error indicates that:

Traceback (most recent call last):
  File "/Users/Echo/Documents/IT/Udacity/python/7.Inheritance/inherentance.py", line 12, in <module>
    print(miley_cyrus.last_name)
AttributeError: Child instance has no attribute 'last_name'

What's wrong with that? Thanks in advance.

Joe Zhow
  • 833
  • 7
  • 17

2 Answers2

3

I am not sure what you are doing but you can get your expected result this way.

class Parent():
    def __init__(self, last_name, eye_color):
        self.last_name = last_name
        self.eye_color = eye_color

class Child(Parent):
     def __init__(self, last_name, eye_color, number_of_toys):
        self.obj = Parent(last_name, eye_color)
        self.number_of_toys = number_of_toys

miley_cyrus = Child("Cyrus", "Blue", 5)
print(miley_cyrus.obj.last_name)
print(miley_cyrus.number_of_toys)

self = Parent should be self.some_variable = Parent

vks
  • 67,027
  • 10
  • 91
  • 124
1

I think the answers to this point didn't really get to the actual problem. In my interpretation, you think, that self is some sort of context which you could change manually.

Are you aware, that self really is the instance you are creating? Reassigning it would not only be confusing, it would be wrong - eventough assigning to parameters isn't possible.

You can execute this piece of code which shows you, that you are trying to mutate miley_cyrus into a Parent inside of the Child initializer:

class Parent(object):
    def __init__(self, last_name, eye_color):
        self.last_name = last_name
        self.eye_color = eye_color

class Child(Parent):
    def __init__(self, last_name, eye_color, number_of_toys):
        # hex(id(self)) -> 0x7fe2325a7da0
        self.number_of_toys = number_of_toys

miley_cyrus = Child("Cyrus", "Blue", 5) # hex(id(miley_cyrus)) -> 0x7fe2325a7da0

Also I think that the term initializer is very important here, because you could get confused with conventional languages. Python has a separate magic method which is responsible for actually creating the object (__new__). At the time __init__ is called - you are already operating on the instantiated object. That's why __new__ takes a class-object rather than self.