2016-05-19 14 views
0

プロパティxを含むクラスから継承し、子クラスでこのプロパティを読み取り専用に設定したいとします。親クラスの__init__が元のセッターを使用している場合、これは機能しません。次のコードを考えてみましょう。Python:プロパティのオーバーライド時に予期しない動作が発生する

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") 

私は今Childをインスタンス化しようとした場合のラインself.x = xが呼ばれたとき、ChildxセッターはなくParentxセッターと呼ばれているので、私はAttributeError: Illegal access to xを取得します。 Pythonicの方法でParentのセッターを使用するにはどうしたらいいですか?

self.x = ...Parentの方法で表示されたとき、それは常にParentxセッターの使用をしなければならない、とself.x = ...Childの方法で表示されたとき、それは常にChildxセッターを利用する必要があり、明確にします、例外を発生させます。

+0

このようなプロパティを継承することはできません。クラスの初期化後に 'Child.x = Parent.x.setter(Parent.x.fset)'を実行できます。 –

+0

@AshwiniChaudharyそれは動作しません。これは 'x'を' Child'に対して読み取り専用にしません。 –

答えて

1

は私の代わりにの場合、私はまたChild

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

を取り除くことができます

Parent.x.fset(self, x) 

Parent.__init__

self.x = x 

をスワップアウトすることによって、問題を自分で解決するために管理しました@x.setter、私はを使用します。

+0

子の '@Parent.x.setter'は' x'を読み取り専用にしません。 –

+0

@NizamMohamedはい、子供に 'x'を書き込むと' AttributeError'が発生します。 –

関連する問題