1

Suppose I have the following classes

class Parent: 
    message = "Hello World"
    @classmethod
    def print_message(cls):
        print(cls.message)
    @classmethod 
    def change_message(cls, new_message):
            cls.message =  new_message

class Child_one(Parent):
    @classmethod 
    def print_messsage(cls):
        print (cls.message)
    @classmethod 
    def change_message(cls, new_message):
        cls.message = new_message

class Child_two(Parent):
    @classmethod
    def print_message(cls):
        print(cls.message)

I suppose my question is to what does the cls of child classes refer to, because If I change the static variable message in parent class it rightly changes values of the of message in both children

Parent.change_message("This is new message")
Child_one.print_message() # This is new message 
Child_two.print_message() # This is new message

this is my expected behavior, both of the cls.message refer to the message of parent class. However doing this

Child_one.change_message("I am child one") 

results in behavior such as

Parent.print_message() # This is new message 
Child_one.print_message() # I am child one 
Child_two.print_message() # This is new message 

So the cls.message variable of Child_one no longer points to the message of the parent class.

In other langues such as c++ or c# static changing a static variable of a parent class or a child class results in change in all of the parent and derived classes. Is there a way to duplicate this behavior in python and if not why not?

2 Answers 2

1

Upon Write:

As soon as you assign a something to a member of a class or object while this member does not exist by name, it is created.

The fact, that a member's name is present in the base class does not change anything. It is created in the class itself.

Upon Read:

The name resolution goes then: First try to find a member in the class itself, then in its base classes.

Sign up to request clarification or add additional context in comments.

1 Comment

I understand that, however I don't understand why does python create a new member for Child_one when I set it. It doesn't exist for the Child_one, but since it's a derived class shouldn't it check if it's parent class has a member called message and only then decide to create it? Doesn't ignoring parent classes upon write violate the is a relationship
0

Frank-Rene's answer is absolutely correct, and you can see this behavior by observing the memory addresses of the class variable:

print(Parent.message, Child_one.message) #identical memory addresses
Child_one.change_message("something")
print(Parent.message, Child_one.message) #now they are different

This is because each class in Python keeps its attributes in a dunder dictionary (__dict__), and if they are not overriden they will reference the parent until modified.

For your use case, you might be interested in Python's borg design pattern: https://github.com/faif/python-patterns/blob/master/patterns/creational/borg.py

Comments

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.