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


13

Pythonで関数の名前を選択することについて混乱しています。時々 、Pythonは組み込み関数ですが不可欠のような:print機能と文字列の方法find。時々、それらは次のようなものではありません:lenその名前はcalculate_len、たとえばなどの命令型でtypeはなく、find_typeです。

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

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

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

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

rotated_letter数字で回転した文字を表す1文字の文字列を返します。私はrotated_letterそれが値を返すのでrandintランダムモジュールの関数のように使用しましたが、そうではありませんgenerate_randint

したがって、この場合、使用する値を返す関数にどのように名前を付ける必要がありますか?名前を必須にするべきか、それとも名詞にするべきか。他の場合では、次のような、それを行う方法は明らかですブール関数のような、is_evenそしてis_palindrome我々は同じようにそれを作るはい/いいえ質問し、また機能だけで行うと戻り未使用の値(つまり、Noneなど)、printおよびlistメソッドsort


これは、実際には、関数に名前を付ける際に命令を使用する非常に一般的な慣行です(慣例と言えます)。たとえば、関数rotate_letterの回転した文字を格納する変数にどのように名前を付けますか?
JoulinRouge

それはあなたの例のいくつかを考える良い方法ではありません。 lenたとえば、「の長さ」と考える方が適切です-引数のメタレベルの説明を取得しています。
イズカタ

回答:


10

合理的であれば動詞を使用し、名詞が短くて曖昧でない場合は

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

  • make_list(foo)vs list(foo).:名詞は動詞より読みやすいです。また、list実際にはクラスであり、クラスは名詞でなければなりません。
  • open(foo)vs file(foo).:動詞は名詞より読みやすく、名詞よりも動詞に「オプション」を与える方が理にかなっているため、名詞はPython 3で削除されました。 open()唯一の「標準」方法ですPython 3でファイルオブジェクトを作成します。
  • foo.get_bar()foo.bar()foo.bar(仮定fooし、bar両方とも名詞です):「GET」何も追加していません我々はすでに知らなかったことをので最初の選択肢は、右のアウトです。2番目は、a barから抜け出すことがfoo潜在的に高価な操作である場合、および/または副作用を伴う場合に適しています(クラスであるBar(foo)かどうかも考慮することができますBar)。3番目の方法は、これが副作用のない安価な操作であり、代替の実装が高価になる可能性が低い場合に適切です。
  • xs.sort()vs. リストのsorted(xs)場合xs:最初は必須です:リストをソートします。リストをインプレースで変更し、何も返しません。2番目は宣言的です:並べ替えられたリスト、正確にそれが返すものです。両方とも動詞です。

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


ありがとうございました!でfoo.get_bar() )vs.` foo.bar( `対foo.barの違いは何である第二及び第三のは
マフムードムハンマドナゲエブ

3番目は、プロパティまたはベア属性です。2つ目はメソッドです。
ケビン

ですから、私が理解しているのであれば、rotated_letter命令型にせず、宣言型に保つのが適切でしょうか?
マフムードムハンマドナゲエブ

この場合letter、コンテキストによって暗示されているかどうかはわかりません。
ケビン

言及のための+1はlistクラスである
斗山マダラ

0

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特に、あなたがやるべきでないものの良い例であるあなたのあなたは、次のような完全な名前を使用すると予想している:コードlength(短い形式のような、非常に人気のある場合を除きをmaxなど)、および動詞を使用し、compute_length。それとも、プロパティを次のようになりますlen([1, 5, 6])なり[1, 5, 6].length。たとえば、C#では、後の形式が使用されますnew [] { ... }.Length

歴史的な理由もあるかもしれないことに注意してくださいlen:C#などのその他の言語Count、通常はメソッドです(残念ながら、.NET Frameworkを介して動作は一貫していませんが)。Countは動詞なので、直感的に、メソッドとして呼び出す傾向があります。

値を返す、またはアクションを実行する

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

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

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

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

  • 環境に影響を与えずに値を返す、純粋なものにすることができます。例:road.measure_distance()

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

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

  • 何もできず、何も返しません。例:time.sleep(1)

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


答えは「はい」だと思いますが、質問しなければなりません。Pythonの観点から完全に答えていますか?他の言語では、関数とプロパティの分離が常に正しいとは限らないためです。また、関数が「アクションを実行する必要がある」ことも事実ではありません。これはPythonの規則ですか?(私はPythonを書いていますが、すべてのPEPを読んでいませんし、私は間違いなく専門家ではありません。
アンドレスF.

@AndresF .: Pythonの観点から答えています。プロパティが存在し、していないJavaなどの言語でgetSomethingそしてsetSomething代わりにプロパティを使用いつもの名前です。
Arseni Mourzenko
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.