Python の関数、メソッドの命名について
get を使わない。
原則、副作用の無く新たにオブジェクトを生成しない関数, メソッドは原則「名詞」を使うのが望まい。
# x
noun = obj.get_noun()
# o
noun = obj.noun()
Getter/Setterは悪だ。以上
もし get がダメなら、give ならどうだろう、とか考えてしまった笑 obj がすでに持っているオブジェクトを get しろというのは、文章としておかしい。ならば tell とか give ならと思った。
確かにそれっぽいけど。最終的に値を生成した関数やメソッドは、例えば create_new_user() みたいなのも create して tell が入ってるけど その tell は省略されてるから tell, give みたいなのは省略するのがいい感じかな..
そんなコードみたことないし obj.noun() が妥当そう.., 自明な文言は削除するってことかな..
# noun = obj.give_noun() # me をつけるともっとそれらしい笑 noun = obj.tell_me_max() # うーん笑 noun = obj.give_me_chocolate()
もしディスクリプタを使えば、より自然に getter, setter を表現できます。
Effective Python の 「4 章 メタクラスと属性」で説明されています。
noun と create, make, generate の使い分け
# 新しいオブジェクト, identity を生成しない。
obj.noun()
# 新しいオブジェクト, identity を生成する。
obj.create()
obj.make()
obj.generate()
でもこの流れでいくと create, make, generate をつけるのは
どうするべきか?
create と make と generate の使い分け
返り値をもつ関数名は、以下のいずれかになるかな。
# 引数と返り値で型が変わらない場合 obj.make() make(obj) # 例 make_sorted_list(list_)
# 引数と返り値で型が変わる場合, 変換して生成されるもの obj.generate() # 例えば tree から list を生成 tree.generate_list()
# 引数の値をもとに全く別のオブジェクトを作り出す場合 obj.create() # 年齢、学籍番号を元に学生を生成する create_student(age, register_id) # でも、普通ならコンストラクタ使うか # ClassName(parameters) Student(age, register_id) # そう考えると create とコンストラクタは等価な関係やな..
What is the difference between create and generate and make ? | HiNative
変数名に引数名を含めるかどうか
考え方: フルネームで記載する。自明なものを削る。
関数名に引数名をつけ加えるのはひどく冗長な感じがする。
1. 同様の機能を持つものが他になければ
例1
def add_a_and_b(a, b): return a + b
2つのものを足すのは明らかななので
def add(a, b): return a + b
例2
def insert_int_to_list(lst, ii): lst.append(i)
# 不要 def insert(lst, i): lst.append(i)
今後の拡張を考えれば、たとえ直近で不要であっても事前に分けておくことも、ひとつの手かもれない。
2. 同様の機能を持つものが2つ以上あれば
Java と違って、メソッドのオーバーロードが無い。型宣言がないが故に逆に、型を意識してコーディングしないといけない。
def insert(dct, integer): ... def insert(lst, integer): ...
# 関数名で分ける。 # 関数名を付けるのも異なるところまでで def insert_to_list(lst, integer): ... def insert_to_dct(dct, integer) ...
あるいは __init__ で場合分けとかも手かもしれない... https://stackoverflow.com/questions/6434482/python-function-overloading
codic 新人プログラマーに読ませて 欲しいネーミングの大切さ
オブジェクトの集まりを表現する変数名
特に list を複数形の名詞で表現した時に for 文で要素を取り出した時に困ります。 例えば members とすると for 文では for member in members となり s がついてるか、ついてないかだけの違いしかでなくて読みづらい。
◯ 集合を表現する変数名
たぶん、これが一番いいと思う。
def average_age(group): # 初期値 sum_member_age = 0 for member in group: sum_member_age += member[AGE]
◯ ハンガリアン記法
もし無いならハンガリアン記法で妥協 orz
def average_age(member_list): # 初期値 sum_member_age = 0 for member in member_list: sum_member_age += member[AGE]
あるいは集合を表す汎用的な表現として container があります。
set, tuple, list, dict などは container と総称することがあります。
でも、 member_container ってのは、ちょっと変な感じがします。
◯ 複数形の s をつける, for 文で回すときは接頭辞に next をつける。
接頭辞に next をつけてしまう。複数形の s を外すだけだとわかりづらいので
def average_age(members): # 初期値 sum_member_age = 0 for next_member in members: sum_member_age = sum_member_age + next_member[AGE]
プログラミング歴ゼロの31歳ジャニヲタ、Pythonを学ぶ。超初心者向けの練習問題を5問紹介。 | Saya’s Blog
for 文はじつは、イテレータで、このように実行されている。
def average_age(members): # 初期値 sum_member_age = 0 while True: try: next_member = next(members) except StopIteration: break sum_member_age = sum_member_age + next_member[AGE]
イテレータで next 取り出したものは、next じゃなくて current やないかなとも思ったりもするけど。今度もう少し考えてみよう。
三人称の s, 複数形の s は、日本人にとって "は" と "わ" と同じくらい間違えると違和感がある。 このへんのコーディングをするときの温度感とかどうなのかなーと思ったりする。next という接頭辞さえいらないのかな...
英語の母語話者にとって複数形の s の有無って、大きな違いと感じるのだろうか.. もしそうなら諦めるか.. 英語圏のコードを意識しながら読んでみよう..
sorted 関数と list.sort メソッド
◯ sorted 関数
sorted(iterable) という、この組み込み関数の命名は、若干命名が異質です。というのも過去分詞の形容詞的用法になっています。
# 使い方 sorted(iterable) # 日本語で表現するなら ソートされた(iterable)
おそらくイメージ的には
# これを sorted_list = make_sorted_list(list_) # 省略した感じ sorted_list = sorted(list_)
◯ list.sort メソッド
このように書いた理由は、おそらく list.sort メソッドとの名前がかぶるのを避けるためだと思われます。
list_object.sort()
また、命名規則だけでなく、動作も異なり list.sort メソッドは sorted 関数と異なり計算した結果を返しません。
なぜ list.sort() はソートされたリストを返さないのですか?
パフォーマンスが問題となる状況では、ソートするためだけにリストのコピーを作るのは無駄が多いです。そこで、 list.sort() はインプレースにリストをソートします。このことを忘れないため、この関数はソートされたリストを返しません。こうすることで、ソートされたコピーが必要で、ソートされていないものも残しておきたいときに、うっかり上書きしてしまうようなことがなくなります。
◯ 命名規則についてもう少し...
# やたら長い関数名 make_done_return_value(obj) # こんな感じで "逃げる" # ただし、一般的な書き方ではない。 # done された obj みたいな意味合いで done(obj)
次の2つを考慮すると...
1. make_done_return_value(obj) だと関数名が長くなる。
2. 副作用の無い関数, メソッドは原則「名詞」を使うのが望ましい。
命名方法が出現する。
return_value = done(parameter)
返り値=過去分詞(引数)という関数の命名はよくあるやり方なのか。"はてな" で質問して見たら、swift とかで若干あったりするらしいが、多くはないというお話をいただく。
なぜ Python では sorted 関数を sorted と命名したのでしょうか?