【pythonエラー対処法】TypeError: hoge() takes 0 positional arguments but 1 was given

python

HelloWorldから始まり、FizzBuzzと順調にPythonのサンプルコードを完成させていくと、少し複雑な関数を使用したり、関数を自作するようになります。
そんな時に突然現れて心を折ってくるエラーとしてTypeErrorがあります。

今回はPython学習者ならだれもが見たことあるTypeErrorについて、原因と対処法をご紹介します!

エラー内容

def add(a,b):
  return a+b
print(add(1,2,3))

上のようなpythonコードを記述し実行すると、次のようなエラーが出てしまいます。

TypeError: add() takes 2 positional arguments but 3 were given

このエラーメッセージを読むと「add()は2つの引数を受け取るが3つ渡された」ことによって引き起こされたエラーであることがわかります。
ここでadd()や2、3という数字はエラーが起きているコードによって異なります。

エラーの原因と対処法

エラーメッセージにある通り、このエラーは関数が要求している引数の数と実際に渡した引数の数が異なっているときに発生します
上の例では、add()という関数はaとbという二つの引数受け取るように設計しています。
しかし関数を利用する段階でadd(1,2,3)と三つの引数を渡してしまっているため、エラーが出てしまっています。
すなわちエラーメッセージには、本来いくつの引数が渡されるべきであり、現在いくつの引数が渡されてしまっているのかが記述されています

このエラーが起きる主な原因は三つあり、それぞれについて対処法を以下にご紹介します。

(1) 関数使用時のミス

まず最も多い原因として、上の例のように関数の使い方を間違えている場合が挙げられます。
自作の関数であれば再度自分の作った関数の引数の数を確認し、関数使用時に同じ数の引数を渡すように書き換えることでエラーは回避できます。
上の例であれば、print(add(1,2))などと書き換えることでエラーがなくなります。

頻繁に引数の数を間違える場合は、キーワード引数を使うことで引数の数の間違いを防止できます。
今回の場合はadd関数の引数としてaとbという引数を要求しているので、以下のように関数利用時にaとbを直接指定してやります。

print(add(a=1, b=2))

設計していない引数を指定することができなくなるため、キーワード引数の利用はミス防止に大きく貢献します。

(2) 関数設計のミス

(1)の時とは逆に、作成した関数のほうが間違っているという場合もあり得ます。
例えば二つの引数を受け取って合計を返すadd関数を作ったつもりが、以下のように記述してしまっていた場合が挙げられます。

def add(a):
  return a+b
print(add(a,b))

先に関数を使う箇所を書いてから、具体的な関数を作成していくというフローでコーディングする際に起こりがちなミスです。
この場合も、関数が本来受け取るべき引数の数をしっかりと確認して一致させることでエラーを直してください。

(3) クラスを自作した時によくあるミス

最後に、Python初心者が必ずハマってしまうミスについてご紹介します。
それはPythonのクラスを自作した時に発生するTypeErrorです。
以下のようにPersonクラスを作成し、クラスのsayHello関数を呼び出すことでHelloと表示させるプログラムを考えます。

class Person:
  def sayHello():
    print('hello')

p = Person()
p.sayHello()

このプログラムを実行すると次のようなエラーが出てしまいます。

TypeError: sayHello() takes 0 positional arguments but 1 was given

sayHello関数が要求する引数は0個、渡している引数も0個のため一見問題がなさそうなコードですが、ここにはPython特有の罠が潜んでいます。

Pythonのクラス内で関数を定義するときには、引数の一つ目にかならずselfを取らなければならない、という決まりがあるのです。
selfとはクラス自身を指す変数で、selfを受け取ることでその関数がクラスに属していることを関数に教えてあげなければなりません。

クラスに属する関数としてsayHello関数を呼び出したとき、この関数はクラスに属しているため自動的にselfという変数が引数として渡されてしまいます
そのため、見かけ上は引数の数があっているにもかかわらず、sayHello関数には引数が一つ渡されてしまっているためエラーが出ているのです。

すなわち、上のコードは以下のように書き換える必要があります。

class Person:
  def sayHello(self):
    print('hello')

p = Person()
p.sayHello()

こうすることで、sayHello関数を呼び出すことで自動的に渡されるselfを受け取れるようになり、エラーも無事直ります。

このエラーは、Javaなどの言語をすでに勉強している人が陥りがちといえます。
Python独特の仕様なので、慣れるまでは忘れずにselfを書いたかどうかを確認しましょう。

python
pickleでエラーならdillで保存する!【Python】

Pythonのpickleを使うと、いろいろなデータを保存出来て便利ですよね。 しかし、ファイルオブ …

python
1
【WP REST API解説】投稿を更新する(POST /posts/id)

Word PressのAPIを用いてすでに投稿されている記事を更新する方法について説明します。 あわ …

python
【対処法】pip install mecab-python3のエラー

久しぶりに自然言語処理の環境を一から作るとき、形態素解析器MeCabのインストールでコケることがよく …