Address
304 North Cardinal St.
Dorchester Center, MA 02124
Work Hours
Monday to Friday: 7AM - 7PM
Weekend: 10AM - 5PM
Address
304 North Cardinal St.
Dorchester Center, MA 02124
Work Hours
Monday to Friday: 7AM - 7PM
Weekend: 10AM - 5PM
今回はPython初心者が組み込み関数のlist()関数をつかって新しくリストを作ろうとしたときに、うっかりハマってしまいがちなちょっとしたトラブルを解決する方法を解説します。
上述のようにPythonで新しくなにかのリストを作ろうとしたときに、
TypeError: ‘list’ object is not callable
このようなメッセージが表示されて、list()が使えない場面に遭遇することがあります。
上述のように、
TypeError: ‘~’ object is not callable
というメッセージが出現する場合は、そのオブジェクトが、
__call___()メソッド
を持っていないということを意味します。
次の例を見てください。
a = 1
まず整数の「1」を代入したオブジェクトa(int型)を作りました。
これを関数のように実行してみましょう。
a() # TypeError: 'int' object is not callable
このようにエラーがでます。そこでオブジェクトaが、__call__メソッドをもっているか確かめてみましょう。
dir(a.__class__)
__class__の理解についてはPythonのクラスについての初歩的な知識が必要となりますが、今回はそれは省略します。大雑把に、「a.__class__は、オブジェクトaを作り出したクラス」のことだと思っていてください。
なぜ、クラスのことを調べるのかというと、Pythonの仕様として、
インスタンスはクラスが call() メソッドを持つなら呼び出し可能です。
Python公式ドキュメント:callable(object)
と書かれているからです。ここでいうインスタンスとは、オブジェクトaのことです。
さて結果は、
['__abs__', '__add__', '__and__', '__bool__', '__ceil__', '__class__', '__delattr__', '__dir__', '__divmod__', '__doc__', '__eq__', '__float__', '__floor__', '__floordiv__', '__format__', '__ge__', '__getattribute__', '__getnewargs__', '__gt__', '__hash__', '__index__', '__init__', '__init_subclass__', '__int__', '__invert__', '__le__', '__lshift__', '__lt__', '__mod__', '__mul__', '__ne__', '__neg__', '__new__', '__or__', '__pos__', '__pow__', '__radd__', '__rand__', '__rdivmod__', '__reduce__', '__reduce_ex__', '__repr__', '__rfloordiv__', '__rlshift__', '__rmod__', '__rmul__', '__ror__', '__round__', '__rpow__', '__rrshift__', '__rshift__', '__rsub__', '__rtruediv__', '__rxor__', '__setattr__', '__sizeof__', '__str__', '__sub__', '__subclasshook__', '__truediv__', '__trunc__', '__xor__', 'as_integer_ratio', 'bit_length', 'conjugate', 'denominator', 'from_bytes', 'imag', 'numerator', 'real', 'to_bytes']
ここに、__call__()メソッドは存在しません。
一方、listについて調べてみましょう。
dir(list.__class__)
結果は、
['__abstractmethods__', '__base__', '__bases__', '__basicsize__', '__call__', '__class__', '__delattr__', '__dict__', '__dictoffset__', '__dir__', '__doc__', '__eq__', '__flags__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__instancecheck__', '__itemsize__', '__le__', '__lt__', '__module__', '__mro__', '__name__', '__ne__', '__new__', '__prepare__', '__qualname__', '__reduce__', '__reduce_ex__', '__repr__',
'__setattr__', '__sizeof__', '__str__', '__subclasscheck__', '__subclasses__', '__subclasshook__', '__text_signature__', '__weakrefoffset__', 'mro']
__call__()メソッドが存在します。
普通はlistはこうなっています。
さて、上述の説明でピンときた方もいるかと思いますが、エラー「TypeError: ‘list’ object is not callable」となる理由は、ようするにlist.__class__が、__call__()メソッドを持っていない状態になっているからです。
そのようになる一例として、
fruits = 'Apple', 'Orange', 'Berry'
list = [1, 2, 3]
fruits_list = list(fruits) # TypeError: 'list' object is not callable
この2行目のように、変数名に「list」そのものを指定し、オブジェクトlistを作ってしまっている場合です。こうしてしまうと、listという情報がPython標準の状態から変わってしまいます。
そうなると、もとものlist()のlistという関数(実際は関数そのものではないのですが)は、ここで作ったオブジェクトlistへ置き換わってしまいます。
実際、上の例において、
dir(list.__class__)
を実行すると、
['__add__', '__class__', '__contains__', '__delattr__', '__delitem__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__getitem__', '__gt__', '__hash__', '__iadd__', '__imul__', '__init__', '__init_subclass__', '__iter__', '__le__', '__len__', '__lt__', '__mul__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__reversed__', '__rmul__', '__setattr__',
'__setitem__', '__sizeof__', '__str__', '__subclasshook__', 'append', 'clear', 'copy', 'count', 'extend', 'index', 'insert', 'pop', 'remove', 'reverse', 'sort']
ここには、__call__()メソッドがありません。すなわち呼び出し可能ではありません。
これはまさに、listが、上でいう
a = 1
のオブジェクトaのようになってしまっていることを意味します。
以上のことからすでにお気づきかもしれませんが、ようするに、
list = ~
このように、変数名「list」となっているものを変更して、別の変数名にしましょう。new_listとか、fruits_listとか。
そしてその次に、一度Pythonのプログラムを終了させ(エディタやターミナルなどを閉じて)ましょう。これをしないと、一度設定してしまった、
list = ~
という情報が残ってしまうため(ブラウザでいうキャッシュのような感じ?)、一度エディタやターミナルを終了させてそれらの情報を消してしまわないと、いくら変数名を変更しても、その残された情報を使ってプログラムが動いてしまうからです。