ローレンスKoppenolのでここで働くと神託たとえば、簡単です、良いアイデアですが、彼の例のコードは、両方の多くの方法で破壊され、それがために持っているよりも複雑されproperties
(計算された属性のためのPythonの汎用的なサポート)を使用して提案しました(なしUpdatable
クラスにも、他の余分なものは必要ありません):あなたがwidth
値をキャッシュしたい場合は(無用な計算を避けるために)まだlength
またはperimeter
変更、あなたがする必要がありますときに更新されますことを確認してください
class Rectangle(object):
def __init__(self, length, perimeter):
self.length = length
self.perimeter = perimeter
@property
def width(self):
return 0.5*(self.perimeter - 2.*self.length)
それらをすべてのプロパティにする:
class Rectangle(object):
def __init__(self, length, perimeter):
self.length = length
self.perimeter = perimeter
@property
def length(self):
return self._length
@length.setter
def length(self, value):
self._length = value
self._width = None
@property
def perimeter(self):
return self._perimeter
@length.setter
def perimiter(self, value):
self._perimeter = value
self._width = None
@property
def width(self):
if self._width is None:
self._width = 0.5*(self.perimeter - 2.*self.length)
return self._width
か(あなたは、このような多くのものを持っている場合)は、この1のように、いくつかの「cached_property無効と」実装を使用します。Storing calculated values in an object
編集:WRT /あなたの質問に、locals
への呼び出しは確かに醜いです(と簡単に壊れる可能性があります - _vars
の部分ではないと思われるローカル変数があります)、子クラスにself._vars
を明示的に設定する必要があります。また、update()
API自体がかなり醜いIMHOです。今、あなたは全体のことをもっとニシキヘビにするために派手な何かを必要としない - ここでは、その唯一の定型(位置のものでは動作しません)名前付き引数とUpdateable.__init__
を呼び出す必要がある解決策です:として
class Updateable(object):
def __init__(self, **kwargs):
self._vars = kwargs
def update(self, **kwargs):
vars = self._vars.copy()
vars.update(**kwargs)
self.__init__(**vars)
class Rectangle(Updateable):
def __init__(self, length, perimeter):
super(Rectangle, self).__init__(length=length, perimeter=perimeter)
self.length = length
self.width = 0.5*(perimeter - 2.*length)
r = Rectangle(10, 20)
r.update(perimeter=40)
サイドノートでは、I personnalyあなたRectangle
クラスがperimeter
引数を取りますが、代わりにwidth
を保存することは極めて憂慮見つける...たぶん、あなたはperimeter
プロパティを考慮する必要がありますか? (読み取り専用などを再計算避けるためにも)
オブジェクトがすでに存在している__init__'後に 'を呼び出すと、少し奇妙に思えます。 'recalculate_width'メソッドや何かを持っていないのはなぜですか? – BrenBarn
私はそれが私が持っている他のクラスのために働きたいので、すべてが異なる引数名を持っています。ときには「幅」、時には「角度」、時には「波長」、何でもかまいません。 –