2016-05-19 6 views
0

Ich möchte von einer Klasse erben, die eine Eigenschaft x enthält, und diese Eigenschaft in der untergeordneten Klasse schreibgeschützt machen, indem Sie den Setter überschreiben. Dies funktioniert nicht, wenn __init__ in der übergeordneten Klasse den ursprünglichen Setter verwendet. Betrachten Sie den folgenden Code.Python: Unerwartetes Verhalten beim Überschreiben von Eigenschaften

class Parent: 
    def __init__(self, x=1): 
     # I want the following line to use the setter defined in the Parent 
     # class, even when __init__ is called from Child using super. 
     self.x = x 
     # Other initialization of Parent goes here. 

    @property 
    def x(self): 
     return self._x 

    @x.setter 
    def x(self, value): 
     """Check that x is non-negative.""" 
     if value < 0: 
      raise ValueError("x must be non-negative.") 
     self._x = value 


class Child(Parent): 

    def __init__(self): 
     super().__init__() # Need this for initialization. 

    @property 
    def y(self): 
     return self._y 

    @y.setter 
    def y(self, value): 
     """x can only be written to implicitly by setting y.""" 
     self._y = value 
     self._x = abs(value) 

    @property 
    def x(self): 
     return self._x 

    @x.setter 
    def x(self, value): 
     raise AttributeError("Illegal access to x") 

Wenn ich jetzt versuchen Child zu instanziiert, bekomme ich AttributeError: Illegal access to x weil, wenn die Leitung self.x = x genannt wird, die x Setter von Child anstelle des x Setter von Parent genannt wird. Wie kann ich es erreichen, den Setzer von Parent in einer pythonischen Weise zu verwenden?

klar sein, wenn self.x = ... in einem Verfahren zum Parent erscheint, soll es immer die Verwendung des x Setter in Parent machen, und wenn self.x = ... in einem Verfahren zum Child erscheint, es sollte immer die Verwendung des x Setter in Child machen und erhebe so eine Ausnahme.

+0

Sie können Eigenschaften wie diese nicht erben, Sie können Folgendes tun: 'Child.x = Parent.x.setter (Parent.x.fset)' nach der Klasseninitialisierung. –

+0

@AshwiniChaudhary Das funktioniert nicht. Es macht "x" nicht schreibgeschützt für "Kind". –

Antwort

1

gelang es mir, das Problem selbst zu lösen, indem

Auslagern
self.x = x 

in Parent.__init__ mit

Parent.x.fset(self, x) 

kann ich auch

@property 
def x(self): 
    return self._x 

in Child loswerden, wenn statt @x.setter, verwende ich @Parent.x.setter.

+0

'@ Parent.x.setter' in Kind würde' x' nicht schreibgeschützt machen. –

+0

@NizamMohamed Ja, es würde, seit dem Versuch, auf das Kind 'x' zu schreiben, einen' AttributError' auslösen würde. –