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

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

新規登録して質問してみよう
ただいま回答率
85.48%
Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

Q&A

解決済

2回答

573閲覧

Pythonのクラスのselfについて

kakini

総合スコア40

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

1グッド

0クリップ

投稿2017/10/27 07:47

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

import random

class Dice:
[tab]face_num=6
[tab]def shoot(self):
[tab][tab]return random.randint(1,6)

これをdice.pyと保存した後
インタラクティヴシェル(=コマンドプロンプト?)で下記のよう操作を実行しました。

import dice
sai=dice.Dice()
sai.shoot()

2
この様な勉強をしました。

ここからが本題で
この後、本の中ではface_num=6が全く使われてないからこれを活用しようという
ことになり、下記の様なスクリプトが出てきます

import random

class Dice:
[tab]face_num=6
[tab]def shoot(self):
[tab][tab]return random.randint(1,face_num)

この後先ほどと同じようにインタラクティヴシェル(コマンドプロンプト?)

reload(dice)
sai=dice.Dice()
sai.shoot()

と入力するように指示されます
しかしこれはわざと間違えてきちんと動かない例を教えています
エラーの理由は関数(def shoot)の内部では外の変数が見る事が出来ないからで
その後正しいスクリプトが下記の様に記載されます

import random

class Dice:
[tab]face_num=6
[tab]def shoot(self):
[tab][tab]return random.randint(1,self.face_num)

本の説明では、これで動くのは

自分自身をselfで参照することに決めておけば、sai.shoot()というコードが実行されたとき、Python内部で自動的にsaiという名前が付いたインスタンスをselfという名前にして、shootメソッドに渡してくれます

この様に書かれてますが、ここがきちんと理解できなくて
自分なりに考えた結果下記のような言い方で解釈してるのですが合ってますでしょうか?

コマンドプロンプトで
変数saiに

sai=dice.Dice()

のサイコロ型を代入した後

sai.shoot()

のメソッドを使う時
saiの中にface_num=6という数字が植えつけられており
shoot(self)メソッドの中のselfにsai自身が代入され(sai=self)
その後
return random.randint(1,self.face_num)
このスクリプトのself.face_numがsai.face_numに置き換えられ
sai.face_numというのはDice型の中にあるface_num=6の事を指してるから
きちんと動く

ちょっと図が無いので文章にすると無駄に長くて分かりづらくなりましたが
こんな感じなんですが合ってますでしょうか?
分かりやすい説明(解釈)があればそれを教えていただけないでしょうか

manzyun👍を押しています

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

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

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

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答2

0

ベストアンサー

リファレンスが参考になるかと思います。

メソッドについて特別なこととして、インスタンスオブジェクトが関数の第1引数として渡されます。 例では、 x.f() という呼び出しは、 MyClass.f(x) と厳密に等価なものです。

つまり、次のように書いても正常に動作します。

Python

1>>> sai = Dice() 2>>> Dice.shoot(sai) 33

これを踏まえると、kakiniさんの洞察がどうやら確からしいと言えそうです。


既にquiquiさんがご指摘のとおり、コードを見やすく表示する機能があります。
編集画面を開き、コードを選択した状態で<code>ボタンを押してください。

投稿2017/10/27 07:57

編集2017/10/27 07:59
LouiS0616

総合スコア35660

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

kakini

2017/10/28 04:26

ありがとうございました
guest

0

おおむねその考え方で正しいです。大丈夫です。

こう書き換えると、わかりやすいかもしれないのかなと思って、質問を書き換えてみます。

変数 saiDice型 を代入した後 shoot のメソッドを使う時、 sai の中に face_num=6 という数字が植えつけられており、shoot(self) メソッドの中の selfsai 自身が代入され(sai=self)、その後このスクリプトの self.face_numsai.face_num に置き換えられ
sai.face_num というのは Dice型 の中にある face_num=6 の事を指してるからきちんと動く。

こんな感じでしょうか。

さて、これを一つのソースコードにまとめると、こんな感じになります。

python

1import random 2 3class Dice: 4 face_num=6 5 def shoot(self): 6 return random.randint(1,self.face_num) 7 8sai=dice.Dice() 9print(sai.shoot()) # こちらは実際に実行した際にわかりやすくするため、printを追記しました。

P.S.
とてつもなく小さなことですが、Pythonのコーディングスタイルガイドでは、インデントは半角スペース4つ推奨です ;)

投稿2017/10/27 08:16

manzyun

総合スコア2244

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

kakini

2017/10/28 04:36 編集

回答ありがとうございます。 >>Pythonのコーディングスタイルガイドでは、インデントは半角スペース4つ推奨です コーディングスタイルガイドというのは聞きなれない言葉なのですが つまりこういう場で質問する場合、上記の質問で記載した [tab]face_num=6 [tab]def shoot(self): ではなく [半角で4つ空ける] face_num=6 [半角で4つ空ける] def shoot(self): ※ちょっと、半角で4つ空けて投稿しましたが表示がきちんとされなかったので[半角で4つ空ける]という文章に書き換えてあります ↑の様に投稿した方が回答者の方達も回答しやすいということでしょうか?
manzyun

2017/10/28 07:03

コーディングスタイルガイドという言い方が正しくなかったかもしれません。 ですがPythonの仕様の元となるドキュメント、Python Enhancement Proposals (PEPs)の8番には「こう言うコーディングした方が、他の人がソースコードを読むときにも扱いやすいよね」ということが書いてあります。 PEP 8 -- Style Guide for Python Code | Python.org https://www.python.org/dev/peps/pep-0008/ 有志の方の日本語訳もあります。 はじめに — pep8-ja 1.0 ドキュメント http://pep8-ja.readthedocs.io/ja/latest/ ---- 話は変わりまして、teratail等のMarkDownという書式が使える掲示板では、ソースコードは三連ダッシュ(```)で囲むのが望ましいです。更に言語の指定も加えておくと、ハイライトがついて見やすくなると思います。 以下のような具合です。 ```python print("Hello eggs") ``` teratailのコメント欄ではMarkDownは使えませんが、参考までに。 このサイトで投稿前にどう見えるか大まかに確認するのも良いかもしれませんね。 Markdown Live Preview http://markdownlivepreview.com/
kakini

2017/10/29 03:20

ありがとうございました
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問