一日一万字の感謝の写経

一日一万字の感謝の写経をして強くなります。そのうち本を置き去りにして何かを作り始める予定です。

PythonのメソッドがNoneを返す時

 Pythonのリストのメソッドの一つであるappend()を使用していた時に、以下のようなエラーが発生しました。

>>> a = [1,2,3]
>>> a
[1, 2, 3]
>>> for i in a.append(2):
    print(i)

    
Traceback (most recent call last):
  File "<pyshell#74>", line 1, in <module>
    for i in a.append(2):
TypeError: 'NoneType' object is not iterable

a.append(2)はリスト型だと思っていたのですが、リスト型ではなくNone型だったようです。

>>> type(a.append(2))
<class 'NoneType'>

無意識に犯してしまったミスですが、これにはCommand–query separationというPythonの設計上の原則が関わっているそう。僕が理解した範囲でざっくり説明すると、「ミュータブルなオブジェクトに対するメソッドは、オブジェクトの変更(Command)と、オブジェクトの参照(query)が同時に行われてはいけない」という原則らしいです。確かに、オブジェクトに対する参照でオブジェクトの変更がなされてしまうと不便そうだなって思いますね。変更したときに参照もされてしまうとどこら辺が不都合なのかいまいちわかりませんが・・・

 この原則は自分でクラスを定義するときにも考慮しておいた方がいいかもしれませんね。因みに、公式ドキュメントにもCommand-query separationをほのめかす説明が書かれています。一度、通読したほうがいいかもと思いました。 5. データ構造 — Python 3.6.5 ドキュメント

insert, remove, sort などのリストを操作するメソッドの戻り値が表示されていないことに気が付いたかもしれません。これらのメソッドは None を返しています。[1] これは Python の変更可能なデータ構造全てについての設計上の原則となっています。

というわけで、ものぐさせずに

>>> a = [1]
>>> a.append(2)
>>> for i in a:
    print(i)

    
1
2

みたいに、メソッドはメソッドで分離しましょう!

入門 Python 3

入門 Python 3

みんなのPython 第4版

みんなのPython 第4版