質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

90.75%

  • Python 2.7

    1205questions

    Python 2.7は2.xシリーズでは最後のメジャーバージョンです。Python3.1にある機能の多くが含まれています。

Pythonのクラスの中で定義するメソッド(関数について)

解決済

回答 2

投稿

  • 評価
  • クリップ 1
  • VIEW 234

kakini

score 4

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"<stdin>",line 1, in<module>
TypeError: shoot() takes exactly 1 argment (2 given)

何がいけないんでしょうか?
それとインタラクティヴシェル(コマンドプロンプト)で変数saiにデータ型を代入してメソッドを呼び出すときメソッドの引数に下記の様なデータ属性の変数を代入しても同じようなエラーが出るんですが何が駄目なんでしょうか?
>>>sai=dice.Dice()
>>>sai.shoot(sai.face_num)

本にはselfを使ったらいいよと書いてありましたが
逆にselfを使わなかったらどうやってやるのかと気になったので
上記の様なものを試してみたのですが何度試してもうまくいきませんでした

  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 2

checkベストアンサー

+2

第一引数にインスタンスが暗に渡されることに留意する必要があります。
次のように定義実装してください。

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 "<stdin>", line 1, in <module>
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.

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2018/01/16 16:02

    回答ありがとうございます。
    すみません、ちょっと確認したい事があるのですが
    その返答する場所を間違えてただの回答の部分に書いてしまったのでそちらの内容が正しいかどうか確認して頂けないでしょうか

    キャンセル

  • 2018/01/16 16:15

    追記しておきました。ご確認ください。
    追加の質問が込み入ったものになる場合、質問文に追記するのが良いかと思います。

    キャンセル

  • 2018/01/16 16:25

    ありがとうございました。
    解決しました

    キャンセル

0

回答ありがとうございます。
試した結果両方ともうまく動きました。
staticmethodはまだ勉強してないからよく分からないので返答を避けさせて頂きます

最初に回答して頂いた部分に対して
念の為、今自分の頭の中にある言葉で説明した内容が正しいのか確認させて頂けないでしょうか
上記で失敗した理由は

import random

class Dice:
    face_num=6
    def shoot(v):
        return random.randint(1,v)

この状態で
>>>sai=dice.Dice()
>>>sai.shoot(6)
と実行した場合、sai.shoot(6)はDice.shoot(sai,6)の様に置き換えられてしまうので
shootメソッドを実行したらvの部分に6ではなくsaiが代入されエラーが起こる

新しいデータ型を作成してその中のメソッドをインタラクティヴシェル(コマンドプロンプト)で使う時
>>>sai=dice.Dice()
>>>sai.shoot(1番目,2番目,3番目)
と入力しても1番目の後ろに0番目の値(この場合sai)が勝手に付いてきて
先に引き渡されるから
メソッドもそれに対応した余分な0番目の引数を
def shoot(self, v)
用意しておく必要がある

これで合ってますでしょうか?

後、一応自分でも入力して確かめてみてきちんと動くのを確認しましたが
回答してくださったスクリプトは

import random

class Dice:
    face_num=6
    def shoot(a,v):
        return random.randint(1,v)


selfでなくても大丈夫ですよね?(この場合はただ邪魔な0番目の値を代入させる為だけに作ったaの部分)

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

15分調べてもわからないことは、teratailで質問しよう!

  • ただいまの回答率 90.75%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

関連した質問

  • 解決済

    AttributeError: 'module' object has no attribute '...

    AttributeError: 'module' object has no attribute 'getInitData' とエラーが出ました。 Data.pyに cla

  • 解決済

    Pythonで別クラスで定義をした関数をあるクラス呼び出す方法

    Pythonでいくつかのclassを定義して、その中で数個の関数を定義しています。 やりたことは、すでに別class内で定義をした関数を現在定義をしているclass内で呼び出す方

  • 解決済

    Pythonの関数内でのselfによる変数の定義について

    質問の概要 Pythonのselfに関して、少し疑問点が見つかりましたので、 質問させて頂きます。 該当のソースコード class Test: def __init__

  • 解決済

    pythonのスライスについて

    a = b[:,0] このようなコードがあったとき、どのようなことがおこなわれますか? bはこのコードがなりたつ何かだとすると なにだったら成り立ちますか? すみません、間

  • 解決済

    リストの情報を他のクラスに渡す

    前提・実現したいこと 随時更新されていくリストの情報を他のクラスに渡したい 発生している問題・エラーメッセージ 今現在三目並べのプログラムを作っていますが、盤の情報を se

  • 解決済

    Pythonのクラスのselfについて

    今「pythonスタートブック」という本で新しいデータ型を作る クラスについて勉強してます この中で分からないのがselfの仕組みです 現在サイコロ型というデータ型を作ろうと本の中

  • 解決済

    ゼロから学ぶDeepLearning 4章についての質問

    前提・実現したいこと 現在ゼロから学ぶDeepLearningを使用して機械学習について勉強しています。 その中で、第四章の二層のネットワーク作成で躓いてしまったことがありました。

  • 解決済

    Classを用いたときにエラーがでる

    生徒番号、名前、テストの点数が書かれたテキストファイルを引数として読み込んで、ある書式で出力するというコードを書いています。 テキストファイルは以下のような例です。 123

同じタグがついた質問を見る

  • Python 2.7

    1205questions

    Python 2.7は2.xシリーズでは最後のメジャーバージョンです。Python3.1にある機能の多くが含まれています。