3
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

初心者がpythonでクラスをやってみた

Last updated at Posted at 2020-06-27

はじめに

今回は「いちばんやさしいPython入門教室」[1]という教材からbouncing balls(跳ねるボール)を使ってクラスオブジェクトを理解していく
理解するにあたって「クラスとselfと__ init __」[2]を使った

クラス

クラスとはオブジェクトの基となる、機能を保存している箱のようなもの。
ここからオブジェクトを作り出す

クラスの作成


class Ball:
    def __init__(self, x, y, dx, dy, color):
        self.x = x
        self.y = y
        self.dx = dx
        self.dy = dy
        self.color = color

これでBallクラスが作成することができた

クラス作成において重要な知識

__init__
コンストラクタと呼ばれるものでオブジェクトを作るときに自動的に呼び出されるもの

self
あとから参照するために使う、オブジェクトの対象(性質・引数)を指し示すために必要なもの
  "self.引数 = 入力された数値"

オブジェクト

オブジェクトとはクラスに属する、具体的な値が定められているもの

オブジェクトの作成

先ほどクラスの作成のつづきを使用する


b = Ball(400, 300, 1, 1, "red")

これでBallクラスの中にBallオブジェクトができた
オブジェクトの内部にある変数 = インスタンス変数
※オブジェクトを作るとき、selfは記入しない

クラス・オブジェクトの利用

実例を見て理解を深める
今回は円を動かすプログラムを先に作ってから、三角・四角を動かすプログラムを追加していく
次のプログラムはクラスの作成のときに使ったBallクラスの続きと考える

円を動かすプログラム


def move(self, canvas):
        # いまの円を消す
        self.erase(canvas)
        # X座標、Y座標を動かす
        self.x = self.x + self.dx
        self.y = self.y + self.dy
        # 次の位置に円を描画する
        self.draw(canvas)
        # 端を超えていたら反対向きにする
        if (self.x >= canvas.winfo_width()):
            self.dx = -1
        if (self.x <= 0):
            self.dx = +1
        if (self.y >= canvas.winfo_height()):
            self.dy = -1
        if (self.y <= 0):
            self.dy = +1
    
def erase(self, canvas):
        canvas.create_oval(self.x - 20, self.y - 20, self.x + 20, self.y + 20, fill="white", width=0)

def draw(self, canvas):
        canvas.create_oval(self.x - 20, self.y - 20, self.x + 20, self.y + 20, fill=self.color, width=0)

このようにBallクラスにmoveメソッドeraseメソッドdrawメソッドを作った

三角・四角を作成する時の重要知識

オーバーライド
既存のクラスを改良・変更して別のクラスを作るときに使う機能

継承
既存のクラスを基に、新しいクラスを作ること
  "class 新しいクラス名(基のクラス名)"

オーバーライド・継承の実例


class Rectangle(Ball):
    def erase(self, canvas):
        canvas.create_rectangle(self.x - 20, self.y - 20, self.x + 20, self.y + 20, fill="white", width=0)

    def draw(self, canvas):
        canvas.create_rectangle(self.x - 20, self.y - 20, self.x + 20, self.y + 20, fill=self.color, width=0)

create_rectangle とは四角を描画するときに使うメソッドで、三角を描画するときは create_polygon (多角形を描画する)というメソッドを使う

ここで書き換えているのは eraseメソッドdrawメソッド だけ
moveメソッドBallクラス から継承される

実行結果

---2020-06-07.png

コーディング完成形


# coding:utf-8
import tkinter as tk
class Ball:
    def __init__(self, x, y, dx, dy, color):
        self.x = x
        self.y = y
        self.dx = dx
        self.dy = dy
        self.color = color

    def move(self, canvas):
        # いまの円を消す
        self.erase(canvas)
        # X座標、Y座標を動かす
        self.x = self.x + self.dx
        self.y = self.y + self.dy
        # 次の位置に円を描画する
        self.draw(canvas)
        # 端を超えていたら反対向きにする
        if (self.x >= canvas.winfo_width()):
            self.dx = -1
        if (self.x <= 0):
            self.dx = +1
        if (self.y >= canvas.winfo_height()):
            self.dy = -1
        if (self.y <= 0):
            self.dy = +1
    
    def erase(self, canvas):
        canvas.delete(self.color)

    def draw(self, canvas):
        canvas.create_oval(self.x - 20, self.y - 20, self.x + 20, self.y + 20, fill=self.color, width=0, tag=self.color)

class Rectangle(Ball):
    def erase(self, canvas):
        canvas.delete(self.color)

    def draw(self, canvas):
        canvas.create_rectangle(self.x - 20, self.y - 20, self.x + 20, self.y + 20, fill=self.color, width=0, tag=self.color)

class Triangle(Ball):
    def erase(self, canvas):
        canvas.delete(self.color)

    def draw(self, canvas):
        canvas.create_polygon(self.x, self.y - 20, self.x + 20, self.y + 20, self.x - 20, self.y + 20, fill=self.color, width=0, tag=self.color)

# 円、四角形、三角形を、まとめて用意する
balls = [
    Ball(400, 300, 1, 1, "red"),
    Rectangle(200, 100, -1, 1, "green"),
    Triangle(100, 200, 1, -1, "blue")
]
def loop():
    # 動かす
    for b in balls:
        b.move(canvas)
    # もう一回
    root.after(10, loop)

# ウィンドウを描く
root = tk.Tk()
root.geometry("800x600")

# Canvasを置く
canvas = tk.Canvas(root, width =800, height =600, bg="#fff")
canvas.place(x = 0, y = 0)

# タイマーをセット
root.after(10, loop)

root.mainloop()

ボールを消す(改定版)

もう一つ、deleteという機能を使ってボールを消す操作の説明をしていく

参考
「いちばんやさしいPython入門教室 修正」[3] と「tkinterのcanvasを使ってみる」[4]
で理解ができたので貼っておく。

deleteとは(コーディング例)

deleteとはカッコ内にtagで指定したオブジェクトを消すことができるもの

   canvas.delete( )


def erase(self, canvas):
        canvas.delete(self.color)

    def draw(self, canvas):
        canvas.create_oval(self.x - 20, self.y - 20, self.x + 20, self.y + 20, fill=self.color, width=0, tag=self.color)

deleteでやることの利点は操作が重くならないこと
(1回ずつ消しているから。白に塗るのだと操作が多くなっていってだんだん重くなっていく)

感想

・ __ init __ や self あたりは理解が難しい。どんどん使っていって慣れていく
・途中で出た bindメソッド (イベントと実行したい関数を結ぶもの)も忘れない

追記

・キャンバスはX軸は右に、Y軸は下に正の向きをとる
・afterメソッドで指定する時間は 1000分の1 秒である

参考文献

[1].「いちばんやさしいPython入門教室」, 大沢文孝著, 株式会社ソーテック社発行
[2]. Webサイト [「クラスとselfと__ init __」] (https://python.ms/class/#はじめに)
[3]. 西谷教授 [「いちばんやさしいPython入門教室」修正] (https://qiita.com/daddygongon/items/53c1206ca4f68a77f1bf)
[4]. qiita記事 tkinterのcanvasを使ってみる

3
2
3

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?