関数はクラスとは大きく異なります。関数を取り、 を に変更したdef
ようclass
です。あなたの場合はほとんどうまくいくと思いますが、それはクラスがどのように進むべきかではありません。
クラスには、関数 (メソッド) とデータが含まれます。たとえば、ボールがあります。
class Ball(object):
# __init__ is a special method called whenever you try to make
# an instance of a class. As you heard, it initializes the object.
# Here, we'll initialize some of the data.
def __init__(self):
# Let's add some data to the [instance of the] class.
self.position = (100, 100)
self.velocity = (0, 0)
# We can also add our own functions. When our ball bounces,
# its vertical velocity will be negated. (no gravity here!)
def bounce(self):
self.velocity = (self.velocity[0], -self.velocity[1])
これでBall
クラスができました。どのように使用できますか?
>>> ball1 = Ball()
>>> ball1
<Ball object at ...>
あまり役に立たないようです。データは役に立つ可能性がある場所です:
>>> ball1.position
(100, 100)
>>> ball1.velocity
(0, 0)
>>> ball1.position = (200, 100)
>>> ball1.position
(200, 100)
わかりました、クールですが、グローバル変数よりも優れている点は何ですか? 別のBall
インスタンスがある場合、それは独立したままになります。
>>> ball2 = Ball()
>>> ball2.velocity = (5, 10)
>>> ball2.position
(100, 100)
>>> ball2.velocity
(5, 10)
そしてball1
独立したままです:
>>> ball1.velocity
(0, 0)
では、定義したbounce
メソッド (クラス内の関数) はどうでしょうか。
>>> ball2.bounce()
>>> ball2.velocity
(5, -10)
このbounce
メソッドによりvelocity
、それ自体のデータが変更されました。繰り返しますが、ball1
触れられませんでした:
>>> ball1.velocity
応用
ボールはきれいですが、ほとんどの人はそれをシミュレートしていません。あなたはゲームを作っています。私たちが持っているものの種類を考えてみましょう:
- 部屋は私たちが持つことができる最も明白なものです。
それでは、部屋を作りましょう。部屋には名前があるため、それを保存するデータがいくつかあります。
class Room(object):
# Note that we're taking an argument besides self, here.
def __init__(self, name):
self.name = name # Set the room's name to the name we got.
そして、そのインスタンスを作成しましょう:
>>> white_room = Room("White Room")
>>> white_room.name
'White Room'
スパイシー。ただし、異なる部屋に異なる機能を持たせたい場合、これはそれほど役に立たないことが判明したので、サブクラスを作成しましょう。サブクラスはそのスーパークラスからすべての機能を継承しますが、さらに機能を追加したり、スーパークラスの機能をオーバーライドしたりできます。
部屋で何をしたいか考えてみましょう。
部屋とやり取りしたい。
そして、どうやってそれを行うのですか?
ユーザーは、応答を受け取るテキスト行を入力します。
どのように応答するかは部屋によって異なるため、 というメソッドで部屋がそれを処理できるようにしましょうinteract
。
class WhiteRoom(Room): # A white room is a kind of room.
def __init__(self):
# All white rooms have names of 'White Room'.
self.name = 'White Room'
def interact(self, line):
if 'test' in line:
print "'Test' to you, too!"
それでは、それを操作してみましょう。
>>> white_room = WhiteRoom() # WhiteRoom's __init__ doesn't take an argument (even though its superclass's __init__ does; we overrode the superclass's __init__)
>>> white_room.interact('test')
'Test' to you, too!
あなたの元の例では、部屋間の移動が特徴でした。current_room
現在いる部屋を追跡するために呼び出されるグローバル変数を使用しましょう。 1赤い部屋も作りましょう。
1. ここにはグローバル変数以外にもより良いオプションがありますが、簡単にするために 1 つを使用します。
class RedRoom(Room): # A red room is also a kind of room.
def __init__(self):
self.name = 'Red Room'
def interact(self, line):
global current_room, white_room
if 'white' in line:
# We could create a new WhiteRoom, but then it
# would lose its data (if it had any) after moving
# out of it and into it again.
current_room = white_room
それでは、それを試してみましょう:
>>> red_room = RedRoom()
>>> current_room = red_room
>>> current_room.name
'Red Room'
>>> current_room.interact('go to white room')
>>> current_room.name
'White Room'
WhiteRoom
読者のための演習:にコードを追加interact
して、赤い部屋に戻ることができるようにします。
すべてが機能するようになったので、すべてをまとめてみましょう。すべての部屋に関する新しいname
データを使用して、プロンプトで現在の部屋を表示することもできます!
def play_game():
global current_room
while True:
line = raw_input(current_room.name + '> ')
current_room.interact(line)
ゲームをリセットする関数を作成することもできます。
def reset_game():
global current_room, white_room, red_room
white_room = WhiteRoom()
red_room = RedRoom()
current_room = white_room
すべてのクラス定義とこれらの関数をファイルに入れると、次のようにプロンプトで再生できます (それらが にあると仮定しますmygame.py
)。
>>> import mygame
>>> mygame.reset_game()
>>> mygame.play_game()
White Room> test
'Test' to you, too!
White Room> go to red room
Red Room> go to white room
White Room>
Python スクリプトを実行するだけでゲームをプレイできるようにするには、これを一番下に追加します。
def main():
reset_game()
play_game()
if __name__ == '__main__': # If we're running as a script...
main()
そして、これはクラスの基本的な紹介であり、それを状況に適用する方法です。