vendredi 7 août 2020

How should a child class call the parent constructor if it has overloaded a property setter?

What is the proper way to call the constructor of a parent class if the child class overloads a property setter and the parent class makes use of a setter in its constructor?

Here is a simple example that demonstrates the question; make a child class that protects a settable attribute of the parent class.

class Parent:
    """Assign attribute in constructor - child fails
    """
    def __init__(self, foo):
        self.foo = foo

class Child(Parent):
    """Protect the settable attribute
    """
    def __init__(self, foo):
        super().__init__(foo=foo)

    @property
    def foo(self):
        return super().foo

Trying to construct Child raises an AttributeError because at run-time the type of self that is passed in super().__init__ is Child, which has protected the attribute foo. If the parent class is rewritten in the following way, constructing the Child works and has protected the attribute foo as desired.

class Parent:
    """Class with a settable attribute - child works
    """
    def __init__(self, foo):
        self._foo = foo
        
    @property
    def foo(self):
        return self._foo

    @foo.setter
    def foo(self, value):
        self._foo = value

My core question here is not how to re-write Parent, but whether there is a way that Child should have been written differently so that the super().__init__ call would work. This seems to show up any time that the Parent class makes use of a setter that a Child class wishes to overwrite.

This seems closely related, but distinct: Overload a property setter in Python

Aucun commentaire:

Enregistrer un commentaire