5

プログラミングパズルを解いたり、小さなスクリプトを書いたりするなど、Pythonで愚かなことをするのが好きです。ある時点で、データを表す新しいクラスを作成するか、すばやくダーティを使用して実行するかというジレンマに直面します。すべての値がリストまたはタプルにパックされています。selfキーワードの極端な怠惰と個人的な嫌悪のために、私は通常2番目のオプションを選びます。

長期的には、ユーザー定義のデータ型の方が優れていることを理解しています。これは、path.min_costおよびpoint.x, point.yよりもはるかに表現力がpath[2]高いためpoint[0], point[1]です。しかし、関数から複数のものを返す必要がある場合、それはあまりにも多くの作業として私を襲います。

だから私の質問は、ユーザー定義のデータ型をいつ作成するか、そしていつリストまたはタプルを使用するかを選択するための経験則は何ですか?それとも、私が気付いていないきちんとしたpythonicの方法がありますか?

ありがとう。

4

3 に答える 3

8

知っていcollections.namedtupleますか?(2.6以降

def getLocation(stuff):
    return collections.namedtuple('Point', 'x, y')(x, y)

または、より効率的に、

Point = collections.namedtuple('Point', 'x, y')
def getLocation(stuff):
    return Point(x, y)

namedtupleと同じ方法でインデックス( point[0])とアンパック()でアクセスできるため、ほぼ簡単なアップグレードパスを提供します。x, y = pointtuple

于 2012-07-23T08:56:10.167 に答える
2

これは確かに主観的ですが、驚き最小の原則を守ろうと思います。

返される値がオブジェクトの特性を説明している場合(例のようpoint.xpoint.y)、クラスを使用します。

それらが同じオブジェクトの一部ではない場合(たとえばreturn min, max)、それらはタプルである必要があります。

于 2012-07-23T08:50:32.987 に答える
2

まず、表現度についての観察。point.xpoint.y対の相対的な表現度について懸念しているとおっしゃいpoint[0], point[1]ましたが、これは複数の方法で解決できる問題です。実際、単純なpoint構造の場合、特にこれを実行できる場合は、クラスがやり過ぎであるという議論があると思います。

x, y = get_point(foo)

point.xこれは、、と同じくらい表現力豊かだと思いpoint.yます。また、(バニラクラスよりも高速である可能性が高く、__dict__ルックアップはありません)、タプルに含まれるアイテムが少ないと仮定すると、非常に読みやすくなります。

クラスに何かを入れるかどうかを決定する私のアプローチは、プログラム全体でデータを使用する方法と関係があります。私は自分自身に「この状態ですか?」と自問します。大きく変化することがわかっているデータがあり、1つの場所に保存して、専用の関数のグループで操作する必要がある場合、データはおそらく状態であることがわかっているので、少なくともデータを挿入することを検討する必要があります。クラス。一方、変更されないデータや一時的なデータがあり、データを使い終えると消える場合は、おそらく状態ではなく、クラスに入る必要はありません。

もちろん、これは単なる経験則です。たとえば、15個の異なるローカル変数がなくても非常に複雑なデータのコレクションを操作できるようにするために、ある種の「レコード」タイプが必要になる場合が考えられます(したがって、が存在しますnamdetuple)。ただし、多くの場合、そのうちの1つまたは2つだけを操作する場合は、1つまたは2つの値を受け入れ、1つまたは2つの値を返す関数を作成する方がよいでしょう。そのためには、タプルまたはリストで十分です。

于 2012-07-23T09:42:03.077 に答える