web-dev-qa-db-ja.com

Pythonで値を返す関数に名前を付けるにはどうすればよいですか?

Pythonで関数の名前を選択することに戸惑っています。時々Python組み込み関数は命令的です:print関数や文字列メソッドfindなど。たとえば、lenなどの名前は必須ではありません。たとえば、calculate_lenなどではなく、typefind_typeではありません。

printは、使用しない値(つまり、None)を返し、何かを実行する(つまり、画面に文字列を表示する)ので、その名前は必須です。

しかし、lenは、使用して何かを行う(つまり、シーケンスまたはマッピングに含まれるアイテムの数を計算する)値を返し、その名前はimperativeではありません。一方、find文字列メソッド(lenとして)は、使用して何かを実行する値を返し、その名前はimperativeです。

この質問をしたのは、Caesar暗号を使用して文字列を暗号化および復号化するスクリプトをレビュー対象に置いたことです。レビュアーは言った:

ただの直感:関数は何かをします。したがって、関数の適切な名前は必須です。rotate_letterではなくrotated_letterを使用します。

rotated_letterは、数字で回転した文字を表す1文字の文字列を返します。 random modulerandint関数のように値を返すため、rotated_letterではありません。generate_randintではありません。 。

したがって、この場合、使用する値を返す関数にどのように名前を付ける必要がありますか?名前をimperativeまたは単なる名詞にする必要があります。 boolean functionsのようなis_evenis_palindromeのように、それを行う方法が明らかな場合もありますはい/いいえ質問、およびNoneやリストメソッドprintなどの未使用の値(つまりsort)を実行して返す関数.

合理的なところでは動詞を使用し、短くて明確な場合は名詞を使用します。

ほとんどの場合、関数は(命令的な)動詞であり、クラス、変数、およびパラメーターは名詞でなければなりません。属性は、_@property_を使用して作成されたものも含めて、名詞でなければなりません。これは、特に副作用がある関数の場合です。[1]関数が何かを返す場合は、動詞が何かを追加するか、単に「ノイズ」であるかを評価する必要があります。

  • make_list(foo)list(foo):名詞は動詞よりも読みやすいです。また、listは実際にはクラスであり、クラスは名詞でなければなりません。
  • open(foo)file(foo):動詞は名詞よりも読みやすく、「オプション」を名詞よりも動詞に与える方が理にかなっているため、名詞は削除されましたin Python 3. 3. open()は、Python 3.でファイルオブジェクトを作成する唯一の「標準」[2]方法です。
  • foo.get_bar()foo.bar()対_foo.bar_(foobarは両方とも名詞であると想定):最初のオプションは完全に「get」は、まだ知らなかったものを追加しないためです。 2番目の方法は、barからfooを取得することが潜在的にコストのかかる操作である場合や、副作用を伴う場合に適しています(Bar(foo) if Barはクラスです)。 3番目の方法は、これが副作用のない安価な操作である場合に適切ですおよび代替の実装では、これが高価になる可能性は低い
  • xs.sort()sorted(xs)xsがリストの場合:最初が必須です:リストをソートします。リストをインプレースで変更し、何も返しません。 2つ目は宣言型です。ソートされたリストであり、正確に返されます。どちらも動詞です。

[1]:通常、値を返すことと副作用があることは、それらを組み合わせるための説得力のある設計上の理由がない限り、相互に排他的です。したがって、副作用がある関数はおそらく何も返さないはずなので、名詞にしてもほとんど意味がありません。
[2]:ioモジュールには、ファイルバッファリング、自動テキストエンコード/デコードなどを追加または削除するために使用できる適度に低いレベルの操作がいくつかあります。名詞はオブジェクト指向クラスであるためです。ほとんどのユーザーはこれらのものを直接操作する必要はありません。代わりに、open()は適切なクラスを選択し、それを自動的にインスタンス化します。

10
Kevin

rotated_letterはメソッドのようには見えません。プロパティのように見えます。つまり、最初のアイデアは次のようにすることです。

var letter = caesar.rotated_letter

letterには、関数ではなく文字列型の値が含まれている必要があります。そこから、次のような別の名前を選択します。

def rotate_letter(self):
    pass

または、代わりにプロパティを使用します。

@property
def rotated_letter(self):
    return self.whatever

lentypeは、他の名前を入力すると長くなるため、このように名前が付けられます。それらは頻繁に使用され、コアPython関数という特別なステータスがあります。すべてのPython=プログラマーはとにかく学習するため、それらの名前はサードパーティライブラリの名前。

特にlenは、-yourコードで実行してはならないことの良い例です。lengthなどのフルネームを使用することが期待されます( maxなどの短い形式が一般的で、compute_lengthなどの動詞を使用します。または、それはプロパティである可能性があります:len([1, 5, 6])[1, 5, 6].lengthになります。たとえば、C#では、後者のフォームnew [] { ... }.Lengthが使用されます。

lenには歴史的な理由もあることに注意してください。C#のような他の言語、優先Count、つまり通常メソッドです(動作は残念ですが) .NET Frameworkを通じて一貫性がない)。 Countは動詞なので、直感的には、メソッドとして呼び出す傾向があります。

戻り値またはアクションの実行

関数は常にアクションを実行することが期待されています。ほとんど値を返さない場合は、プロパティである必要があります。次の場合、関数をプロパティに変換する必要があるというヒントがあります。

  • 関数にreturn ...ステートメントがほとんど含まれていない、

  • 自然に頭に浮かぶ関数の名前は、product.get_price()のようにget_somethingです。

ここで、関数がある場合、それは4つのタイプのいずれかになります。

  • 純粋な場合もあります。つまり、環境に影響を与えずに値を返します。例:road.measure_distance()

  • 何も戻さずに環境に影響を与える可能性があります。例:product_database.remove_record(1234)

  • 環境に影響を与え、値を返す可能性があります。例:value++などのvalue.increment()を使用。

  • それは何もせず、何も返しません。例:time.sleep(1)

名前が関数の型について強いヒントを与えることができるケースはほとんどありませんが、多くの場合、名前から型をほとんど知ることができません。

0