Home > database >  @property decorator behavior with inheritance in python
@property decorator behavior with inheritance in python

Time:09-18

I'm learning the python @property decorator. I am stuck and couldn't able to find the solution. I checked this and this one in SO, but my question is different.

Here, I have created a Base class in which I made the function fun_name as an attribute to this Base class using @property decorator. Everything works as expected.

I want to know about the behavior of this with inheritance.

For this, I have created another class Derived which is derived from the Base class. Here in the Derived class , I am trying to access the property attribute function fun_name using the Derived class member function sample_fun .

Accessing the fun_name attribute directly using the Base class object (obj1) works as expected. But I am confused with the behavior when I am calling the same using the Derived class member function sample_fun using the obj2 object.

class Base:
    def __init__(self,name):
        self.name = name
      
    @property
    def fun_name(self):
        print("Entered the getter fun_name")
        return "Getter-> Hello {}".format(self.name)

    @fun_name.setter
    def fun_name(self,str):
        self.name = str
        print("Setter-> Hello {}".format(self.name))

    def fun_name1(self):
        print("Hello from fun_name1 {}".format(self.name))

class Derived(Base):
    def sample_fun(self):
        print("Calling base call fun directly")
        Base.fun_name1(self)
        print("It works")
        print("Calling base attrib directly")
        
        Base.fun_name     #Here Why it is not entering  into the fun_name ?
        

        print("It prints here but not entering into the fun_name")
        
       
obj1 = Base("Joe")
obj1.fun_name
obj1.fun_name = "Jim"
obj1.fun_name

obj2 = Derived("RAJ")
obj2.sample_fun()

Console output:

Entered the getter fun_name
Setter-> Hello Jim
Entered the getter fun_name
Calling base call fun directly
Hello from fun_name1 RAJ
It works
Calling base attrib directly
It prints here but not entering into the fun_name

As you can see when I am directly accessing it using the Base class object (obj1) , it enters into the function.

But the same behavior is not happening with the Derived class member function. Exactly at the place Base.fun_name in the sample_fun method.

Am I missing some important concept here?

CodePudding user response:

@property adds an instance method that gets triggered on property access. Note the self argument. It adds a property object on the class. When you access an instance of that class, python will call the method and pass the class instance to it.

Base.fun_name is the actual property object on the class. If you did Base().fun_name it would work like you expect. If Base.fun_name DID get called, it would throw an exception because there's no self to get passed.

CodePudding user response:

@Paul Becotte already provide a good solution to the question I asked. I found one more way (anyway already existing) to access the same functionality which I need here. Because the Derived class is already derived from Base class. Hence all the properties of this Base class is available with Derived class. So my question was, how to access the property attribute function fun_name using the Derived class member function sample_fun.

My initial idea was to call like this:

Base.fun_name  #This was wrong and Paul already gave an explanation on this

@Paul's suggestion was:

Base("ANY NAME").fun_name  #This worked and explanation to this also he had given

Another solution of mine (calling with self since it is derived from Base):

self.fun_name #This solution also worked since the Derived class is derived from Base

Many thanks !

  • Related