1

私はPythonのプロパティと、以前と同じようにクラス属性を使用できるようにする方法を知っていますが、その間にいくつかの変更が可能です。

とにかく、最近いくつかの perl をやったので、コードをさらに少なくしてゲッターとセッターを組み合わせるというアイデアが好きになりました

お気に入り:

sub filename {
   my $self      = shift;
   my $filename  = shift;
   if ($filename){ $self->$filename = $filename;}
   else {return $self->$filename;}
}

明らかに、perl ではメソッドの後ろの () を省略できます。これにより、このアプローチが「よりクリーン」になり、クラスのユーザーに対してより透過的になります。

py では、アクセス時に () が必要になるという唯一の欠点である同様のことができます。

def filename(self, setter=None):
    if setter is not None:
         self._filename = setter
    else:
         return self._filename

私にとって、これはプロパティのことを行うよりもはるかにコンパクトであり、私のコードはより読みやすいと思います。

それで、私のアプローチに何か問題がありますか、それとも何らかの理由で一義的ですか?

ありがとう!

4

1 に答える 1

3

最初の問題は、インターフェイスが異なっており、間違いなくわかりにくいことです。 unit.position = new_posに変わりunit.position(new_pos)ます。これは、一部の言語ではミューテーションとして認められているスペルですが、Python ではそれほどではありません。これを行う人はほとんどいません。たとえpropertyが使用されていなくても、通常は個別getの andsetメソッドがあります。言い換えれば、あなたのコードは非慣用的で紛らわしいものとして目立ちます。

その結果、拡張代入演算子は機能しなくなります:unit.position += velocityは不可能です (.positionがプロパティの場合に機能します)。もう 1 つの潜在的な問題は、これがプロパティの への設定をサポートしていないことNoneです。独自のセンチネル値 (NO_VALUE = object()など) を発明する必要があり、試練全体がより醜いものになります。

実装側で想定される利点は非常に小さいです。空行を 1 行または 2 行節約できますが、追加のインデントと条件が必要になります。プロパティは、単に設定または返すだけではないことに注意してください (それ以外の場合は、プロパティであってはなりません)。プロパティ (8 行)

@property
def width(self, new_width):
    self._width = new_width
    self._dirty = True

@width.setter
def width(self):
    return self._width

対 getter-setter-method (6 行):

def width(self, new_width=None):
    if new_width is not None:
        self._width = new_width
        self._dirty = True
    else:
        return self._width

1 つの空白行と 1 つの非空白行を保存しますが、そのために支払う料金は

  • より悪いインターフェース
  • より多くのインデント
  • エラーの可能性が高くなります (例: 状態のタイプミス、忘れelse)
于 2013-05-25T11:47:14.440 に答える