Pythonで関数の名前を選択することに戸惑っています。時々Python組み込み関数は命令的です:print
関数や文字列メソッドfind
など。たとえば、len
などの名前は必須ではありません。たとえば、calculate_len
などではなく、type
はfind_type
ではありません。
print
は、使用しない値(つまり、None
)を返し、何かを実行する(つまり、画面に文字列を表示する)ので、その名前は必須です。
しかし、len
は、使用して何かを行う(つまり、シーケンスまたはマッピングに含まれるアイテムの数を計算する)値を返し、その名前はimperativeではありません。一方、find
文字列メソッド(len
として)は、使用して何かを実行する値を返し、その名前はimperativeです。
この質問をしたのは、Caesar暗号を使用して文字列を暗号化および復号化するスクリプトをレビュー対象に置いたことです。レビュアーは言った:
ただの直感:関数は何かをします。したがって、関数の適切な名前は必須です。
rotate_letter
ではなくrotated_letter
を使用します。
rotated_letter
は、数字で回転した文字を表す1文字の文字列を返します。 random moduleのrandint
関数のように値を返すため、rotated_letter
ではありません。generate_randint
ではありません。 。
したがって、この場合、使用する値を返す関数にどのように名前を付ける必要がありますか?名前をimperativeまたは単なる名詞にする必要があります。 boolean functionsのようなis_even
やis_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
_(foo
とbar
は両方とも名詞であると想定):最初のオプションは完全に「get」は、まだ知らなかったものを追加しないためです。 2番目の方法は、bar
からfoo
を取得することが潜在的にコストのかかる操作である場合や、副作用を伴う場合に適しています(Bar(foo)
if Bar
はクラスです)。 3番目の方法は、これが副作用のない安価な操作である場合に適切ですおよび代替の実装では、これが高価になる可能性は低い。xs.sort()
対sorted(xs)
xs
がリストの場合:最初が必須です:リストをソートします。リストをインプレースで変更し、何も返しません。 2つ目は宣言型です。ソートされたリストであり、正確に返されます。どちらも動詞です。[1]:通常、値を返すことと副作用があることは、それらを組み合わせるための説得力のある設計上の理由がない限り、相互に排他的です。したがって、副作用がある関数はおそらく何も返さないはずなので、名詞にしてもほとんど意味がありません。
[2]:io
モジュールには、ファイルバッファリング、自動テキストエンコード/デコードなどを追加または削除するために使用できる適度に低いレベルの操作がいくつかあります。名詞はオブジェクト指向クラスであるためです。ほとんどのユーザーはこれらのものを直接操作する必要はありません。代わりに、open()
は適切なクラスを選択し、それを自動的にインスタンス化します。
rotated_letter
はメソッドのようには見えません。プロパティのように見えます。つまり、最初のアイデアは次のようにすることです。
var letter = caesar.rotated_letter
letter
には、関数ではなく文字列型の値が含まれている必要があります。そこから、次のような別の名前を選択します。
def rotate_letter(self):
pass
または、代わりにプロパティを使用します。
@property
def rotated_letter(self):
return self.whatever
len
とtype
は、他の名前を入力すると長くなるため、このように名前が付けられます。それらは頻繁に使用され、コア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)
。
名前が関数の型について強いヒントを与えることができるケースはほとんどありませんが、多くの場合、名前から型をほとんど知ることができません。