何事もほどほどにというのは、プログラミングにも言えると思うのでベストな方法はケースバイケースな気はしますが、極端な場合(アプリケーションやモジュール内にこうした論理が多数必要というような場合)ちょっと凝ったことをしてみたくなることもあります。
python
1def callWhenNotNone(f, a):
2 return None if a is None else f(a)
3
4def A(a):
5 assert a is not None # AにNoneはわたってこないはずだがBに万一Noneが渡ると
6 # 危険ならこうしたガードを仕込みたいこともある
7 r = B(a)
8 r = callWhenNotNone(C, r)
9 return callWhenNotNone(D, r)
とか
python
1class GuardedValue:
2 def __init__(self, value):
3 self.value = value
4
5 def applySafe(self, f):
6 if value is None:
7 self.value
8 else:
9 self.value = f(self.value)
10 return self
11
12 def apply(self, f):
13 assert self.value is not None
14 self.value = f(self.value)
15 return self
16
17def A(a):
18 gv = GuardedValue(a)
19 return gv.apply(B).applySafe(C).applySafe(D).value
Swift言語などにあるNull安全機能をちょっとまねてみたというコードです。
ただ下手にこういうことをやると却って可読性が下がったり、必要性の薄い関数やクラスの設計にかけた時間に対して大して得るものが少なかったりと、自己満足に終わる危険が大きいかも知れません。
こうした方法は頭の体操的な意味が多少あるとは思いますが、平易かつ適度な簡潔さで書くという本来的な意味で、多くの場合他の方の回答の方が適切な気がします。
そもそもPythonでこういう配慮をしたくなる大き目のアプリケーションって書くことがあるのか・・・小さめのもの(せいぜい数百行くらい)しか書いたことのない自分にはそのあたりのはっきりとした考えがありません。
呼ぶ側と呼ばれる側のどちらでNoneに対する分岐を書くべきですか?
can110さん回答に同意です。ケースバイケース。Noneに対する分岐も「その関数の機能の一つ」です。呼ばれる側にその機能が本質的に必要なら呼ばれる方に書くべきですしそうでないなら書くべきでないでしょう。
例えば汎用的な初等関数math.powにNoneチェックを入れるべきでしょうか?NOだと思います。この関数の機能は「与えた数値に対して計算すること」だけであって数値以外を渡しても何かの値を返すという機能は不必要と思います。
一方引数にNoneを渡したとき特定の規定値を仮定するといった明確な意義があるならNoneチェックをする意味があるでしょう。例えばNoneを許さない関数を呼び出す必要があり、かつその引数がNoneとなるケースを想定せねばならないAはそういう類の関数と言えましょう。
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。