質問: Pythonで下記の様なサイコロをモチーフにしたデータ型を作り クラス(新しいデータ型)の中にメソッド(関数)を作って「dice」という名前で保存しました ``` import random class Dice: face_num=6 def shoot(v): return random.randint(1,v) ``` インタラクティヴシェル(コマンドプロンプト)を使って >>>sai=dice.Dice() >>>sai.shoot(6) と入力すると下記の様なエラーが出ます Traceback (most recent call last): File"",line 1, in TypeError: shoot() takes exactly 1 argment (2 given) 何がいけないんでしょうか? それとインタラクティヴシェル(コマンドプロンプト)で変数saiにデータ型を代入してメソッドを呼び出すときメソッドの引数に下記の様なデータ属性の変数を代入しても同じようなエラーが出るんですが何が駄目なんでしょうか? >>>sai=dice.Dice() >>>sai.shoot(sai.face_num) 本にはselfを使ったらいいよと書いてありましたが 逆にselfを使わなかったらどうやってやるのかと気になったので 上記の様なものを試してみたのですが何度試してもうまくいきませんでした
回答: 第一引数にインスタンスが暗に渡されることに留意する必要があります。 次のように定義実装してください。 ``` def shoot(self, v): return random.randint(1,v) ``` なお、Pythonでは`sai.shoot(6)`は`Dice.shoot(sai, 6)`と同等に扱われます。 > > 逆にselfを使わなかったらどうやってやるのかと気になったので > > 上記の様なものを試してみたのですが何度試してもうまくいきませんでした > > > なるほど。確かにこのメソッドにはselfが不要です。 このような際は、staticメソッドにすることも解決策の一つになります。 ``` @staticmethod def shoot(v): return random.randint(1,v) ``` 呼び出す際は`Dice.shoot(6)`と呼び出すようにしてください。 ただの関数として定義してもいいかもしれません。このあたりは設計に依ります。 コメントを受けて > > sai.shoot(6)はDice.shoot(sai,6)の様に置き換えられてしまうので > > shootメソッドを実行したらvの部分に6ではなくsaiが代入されエラーが起こる > > > 単純に引数の個数が違うと判断されてしまうからです。 ``` >>> def hoge(a): ... pass ... >>> hoge(1, 2) Traceback (most recent call last): File "", line 1, in TypeError: hoge() takes exactly 1 argument (2 given) ``` > > メソッドもそれに対応した余分な0番目の引数を > > def shoot(self, v) > > 用意しておく必要がある > > > はい。**インスタンスメソッド**の場合そうなります。 > > 後、一応自分でも入力して確かめてみてきちんと動くのを確認しましたが > > 回答してくださったスクリプトは > > (中略) > > selfでなくても大丈夫ですよね? > > > その通りです。selfというのは慣習的に使われているにすぎません。 ただし、self以外の名前を使う合理性がないので、selfを使った方が良いでしょう。 Pythonのコーディング規約であるPEP8(日本語・本家)にも次のように記載されています。 > > Always use `self` for the first argument to instance methods. > > >