1

I have a class Person and 2 classes Child and Adult that inherit from `Person.


class Person:

    def __init__(self, name):
        self.name = name
        self.age = 0

    def say_hi(self):
        print("Hi, I am " + self.name)

    def set_age(self, age):
        self.age = age

class Child(Person):

    def play_with_children(self):
        print("Playing with children")

class Adult(Person):

    def drink_alcohol(self):
        print("drinking")

I want to create an instance from Person then set it's age and according to it this instance should "become" a Child or an Adult.

Also if it's a Child and it's age increases I'd like it to "become" an Adult. Note that this code has an error because the Person's constructor expects a name because it's meant to create a new instance.

person1 = Person("Marvin")

person1.set_age(15)

if person1.age < 21:
    person1 = Child()# This is an error => expects the name
    #But I wouldn't like to handle all members like this => person1 = Child(person1.name)
    #I don't want a new instance, is that even posible?

person1.say_hi() 
person1.play_with_children()


person1.set_age(25)

if person1.age > 21:
    person1 = Adult()# This is an error => expects the name
    #But I wouldn't like to handle all members like this => person1 = Adult(person1.name)
    #I don't want a new instance, is that even posible?

person1.say_hi()   
person1.drink_alcohol()
  • Is this even possible?

  • Can this be done without creating new instances?

PS: this is just a sample code showing the problem from a more complex problem that I have (Not really children and adults :D ).

Ivan
  • 1,352
  • 2
  • 13
  • 31
  • Does this help? https://stackoverflow.com/questions/20722714/python-change-self-to-inherited-class – dspencer Mar 15 '20 at 12:26
  • 1
    @dspencer It does help, just there's no need to implicitly inherit from `object` when working with python 3, thanks! – Ivan Mar 15 '20 at 12:38

1 Answers1

2

As mentioned in the comments, in Python 3 we can access the __class__ of any instance and change it.

Although you must be careful, with this you can add attributes of several classes to the same instance and create a weird monster (methods are safe).

person1 = Person("Marvin")

person1.set_age(15)

if person1.age < 21:
    person1.__class__ = Child

person1.say_hi() 
person1.play_with_children()


person1.set_age(25)

if person1.age > 21:
    person1.__class__ = Adult


person1.say_hi()   
person1.drink_alcohol()

So the monster:

class Dog:

    def wouf(self):
        print("wouf")

person1.__class__ = Dog
print("Attributes are saved, name: "+ person1.name)
#But methods not, so now I can't use person1.say_hi()
person1.wouf()
Ivan
  • 1,352
  • 2
  • 13
  • 31