-1

I'm creating members using the property function, but when I'm trying to override the setters and getters of those properties, it always reference the setters and getters of the parent class:

class A():
    def evaluate(self):
        return 'A'
    value = property(evaluate)

class B(A):
    def evaluate(self):
        return 'B'

b = B()
print(b.value) # I get 'A'

I tried to put the definition of the value member inside the constructor of the parent such as:

self.value = property(self.evaluate)

but when accessing the value of an object it returns a property object not the actual value such as : 'A' or 'B.

<property object at 0x7fecd01a88b8>

I know how to workaround this issue, but I want to know if it is possible to solve it using the property function/decorator and without code repetition.

adnanmuttaleb
  • 3,388
  • 1
  • 29
  • 46
  • [python properties and inheritance](https://stackoverflow.com/questions/237432/python-properties-and-inheritance) – c6754 Sep 24 '18 at 14:57
  • Possible duplicate of [python properties and inheritance](https://stackoverflow.com/questions/237432/python-properties-and-inheritance) – adnanmuttaleb Sep 24 '18 at 16:04

1 Answers1

2

The problem is that the expression property(evaluate) binds the property to the evaluate function that is in scope when the class body for A is executing. To do what you want you would have to delay accessing evaluate until the property is being used.

This would work, but if we knew why you are trying to do this there is probably a much better way:

class A():
    def evaluate(self):
        return 'A'
    value = property(lambda self: self.evaluate())

class B(A):
    def evaluate(self):
        return 'B'

b = B()
print(b.value) # prints 'B'

If all you want to do is return a different constant string for A or B then you don't need a property at all:

class A():
   value = 'A'

class B(A):
   value = 'B'

b = B()
print(b.value)

and if you really need a property then just redefine the property in the subclass:

class A():
   @property
   def value(self):
       return 'A'

class B(A):
   @property
   def value(self):
       return 'B'

b = B()
print(b.value)
Duncan
  • 92,073
  • 11
  • 122
  • 156