2012-04-04 16 views
10

私はクラスを完全に理解していません。私はpythonのドキュメントといくつかの他のチュートリアルを読んでいます。私はそれの基本的な要点を得るが、ニュアンスを理解していない。ここに私のコードでたとえば:Python - クラスとOOPの基礎

class whiteroom(): 
    """ Pick a door: red, blue, green, or black. """ 

    do = raw_input("> ") 

    if "red" in do: 
     print "You entered the red room." 

    elif "blue" in do: 
     print "You entered the blue room." 

    elif "green" in do: 
     print "You entered the green room." 

    elif "black" in do: 
     print "You entered the black room." 

    else: 
     print "You sit patiently but slowly begin to stave. You're running out of time." 
     return whiteroom() 

game = whiteroom() 
game 

(元codepad

私はクラスwhiteroomを返すようにしたいと思います。これは、不可能であるか、正しく行われていないかのどちらかです。クラスを返す方法や2つのクラスを "リンク"して、whiteroomがelseで繰り返され、呼び出されたときに他のルーム(クラスとなる)が返されるようにすれば、それはすばらしいことになります。

また、私は__init__に非常に不安定で、その目的が何であるかまだまだわかりません。誰もが、それが "初期化する"ことを私に伝えています。それは確かですが、それは私の脳を助けてくれるとは思われません。

答えて

37

機能はクラスとは大きく異なります。あなたが機能を取り、ちょうどdefclassに変更したようです。私はのほとんどががあなたのケースでうまくいくと思うが、それはクラスが行く方法ではない。

クラスには、関数(メソッド)とデータが含まれています。たとえば、ボールがあります。

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は独立したまま:

我々が定義されている bounceメソッド(クラス内の関数)について今、何
>>> ball1.velocity 
(0, 0) 

>>> 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つを使用します。

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' 

は演習:あなたが戻って赤の部屋に行くことができますWhiteRoominteractにコードを追加します。

すべての機能が完了しましたので、まとめてみましょう。新しい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 

は、ファイルにクラス定義と、これらの機能のすべてを入れて、あなたは(このようプロンプトでそれを再生することができますPythonスクリプトを実行して、ただのゲームをプレイすることができるようにするに

>>> 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> 

、あなたが一番下にこれを追加することができます:)彼らはmygame.pyにいると仮定し

def main(): 
    reset_game() 
    play_game() 

if __name__ == '__main__': # If we're running as a script... 
    main() 

これは、クラスの基本的な紹介と、それをあなたの状況に適用する方法です。

+2

「ボール」はクラスであってはなりません。経験則:2つのメソッドしかなく、そのうちの1つが '__init__'の場合は、関数と' functools.partial'を使って関数をいくつかのデータにバインドする必要があります。ここに紹介されている他のクラスと同じです。 PythonはJavaではありません!ここで私が見ているのは、クラスでなければならないのはゲームそのものですが、代わりにモジュール全体の状態を使用するのですか? –

+0

ユーザの運動部では、白い部屋から赤い部屋に行くことができるようにしました。でも、私は出来ません。 "if" x "in line:current_room = red_room"を追加しました。現在のルーム変数は変更されません。しかし、もし私が次のようなことをしたら: "if" x "in line:print" this ""それは動作します。あなたの投稿をありがとう。それは非常に有用だった! –

+0

私はそれを考え出した!あなたの助けをもう一度ありがとう:) –

5

私はあなたがこれまでにすべてを聞いたと確信していますが、私はそれを行くでしょう。

クラスは、一連の関数と変数を1つのオブジェクトにグループ化する方法です。あなたがそれに至ると、これは意味をなさないグループにすべてを編成する単なる方法です。物事を理解し、デバッグしたり、拡張したり、維持したりするためのメリットがありますが、基本的には、あなたのメンタルモデルで定義されたものを作るための単なる方法です。

あなたのコードは、あなたのプログラム全体を「オブジェクト」の中に書き込もうとしているようです(本当に間違って記述された関数があります)。

代わりにこれを検討してください。

彼らのドアとホワイトボードが入っている部屋の精神モデルを考えてみましょう。ドアには色があります。また、ホワイトボードにはテキストが書かれています。シンプルにするためにそこに残しておきます。

私には、色の文字列を持つドアオブジェクト、テキストの文字列を持つホワイトボードオブジェクト、ドアとホワイトボードを持つルームオブジェクトの3つのオブジェクトがあります。

は、次のコードを考えてみましょう:

class Door(object): 
    def __init__(self, color): 
     self.color = color 

class Whiteboard(object): 
    def __init__(self, default_text=''): 
     self.text = '' 
     self.write_text(default_text) 

    def write_text(self, text): 
     self.text += text 

    def erase(self): 
     self.text = '' 


class Room(object): 
    def __init__(self, doorcolor, whiteboardtext=''): 
     self.whiteboard = Whiteboard(whiteboardtext) 
     self.door = Door(doorcolor) 




# make a room with a red door and no text on the whiteboard 
room1 = Room('red') 

# make a room with a blue door and 'yeah, whiteboard' on the whiteboard 
room2 = Room('blue', 'yeah, whiteboard') 

# make a room with a green door 
room3 = Room('green') 



# now I can play around with my 'rooms' and they keep track of everything internally 

print 'room 1 door color: ' + room1.door.color 
print 'room 2 door color: ' + room2.door.color 


# all my rooms have a door and a whiteboard, but each one is different and self contained. For example 
# if I write on room 1's whiteboard, it doesn't change anything about room 3s 

print 'room1 whiteboard: ' + room1.whiteboard.text 
print 'room2 whiteboard: ' + room2.whiteboard.text 
print 'room3 whiteboard: ' + room3.whiteboard.text 

print '-- changeing room 1 whiteboard text --' 

room1.whiteboard.write_text('oop is really helpful') 


print 'room1 whiteboard: ' + room1.whiteboard.text 
print 'room2 whiteboard: ' + room2.whiteboard.text 
print 'room3 whiteboard: ' + room3.whiteboard.text 

のinit機能は、あなたのクラスの新しいインスタンスを初期化する「」がオンのときに呼び出されるものです。この例では、3つのルームオブジェクトを作成して、それぞれがドアとホワイトボードオブジェクトを内部的に作成しています。私がコンストラクタに渡すパラメータRoom(parameter1, parameter2)は、init関数に渡されます。これを使用して、ドアの色とオプションでホワイトボード上のテキストを設定することができます。また、オブジェクトに属している変数はselfで参照されています。この参照はすべてのクラス関数の最初のパラメータとして渡されます(後でクラスやその他の高度な機能を拡張するときに重要になります)。

2

よく私はLearning Python by Mark LutzからPythonのOOPSを理解しました。これはPythonコンセプトを理解するための包括的なソースであり、特にPythonicのコードになります。

オンライン参照のために、私はthisサイトのチュートリアルが好きです。 postを実行すると、initの手助けとなります。 PythonのOOPは、理解して実装するのが非常に簡単です。最初は難しいようですが、いくつかの基本的なOOPコードをプログラミングした後は簡単です。 学習をお楽しみください。

2

あなたは本当に遠いです。

申し訳ありませんが、これはほんの救済可能です。

class Room(object): 
    ''' A generic room ''' 
    def __init__(self): 
     self.choices = None 
     self.enter() 
    def enter(self): 
     ''' Enter the room, to be filled out in subclass ''' 
     pass 
    def print_choices(self): 
     '''You are stuck bro''' 
     print "You are stuck bro" 

を次にあなたがそうのようwhiteroomのような特定の部屋を作ることができます:私は、例えば、あなたが部屋のクラスのような何かをしたい伝えることができるものから、

class Whiteroom(Room): 
    ''' A white room ''' 
    def __init__(self): 
     self.choices = ["red", "blue", "green", "black"] 
     self.enter() 
    def enter(self): 
     print "You sit patiently, but slowly begin to starve. You're running out of time." 
    def print_choices(self): 
     print "You can choose from the following rooms:" 
     print self.choices 

class Blackroom(Room): 
    ''' A black room ''' 
    def enter(self): 
     print "It's really dark in here. You're out of time." 

class Redroom(Room): 
    ''' A red room ''' 
    def __init__(self): 
     self.choices = ["black", "blue", "green", "white"] 
     self.enter() 
    def enter(self): 
     print "It's getting hot in here. So take off all your clothes." 
    def print_choices(self): 
     print "You can choose from the following rooms:" 
     print self.choices 

class Blueroom(Room): 
    ''' A blue room ''' 
    def __init__(self): 
     self.choices = ["black", "red", "green", "white"] 
     self.enter() 
    def enter(self): 
     print "It's nice and cool in here. Stay awhile if you want." 
    def print_choices(self): 
     print "You can choose from the following rooms:" 
     print self.choices 

class Greenroom(Room): 
    ''' A green room ''' 
    def __init__(self): 
     self.choices = ["black", "red", "blue", "white"] 
     self.enter() 
    def enter(self): 
     print "You won." 

その後、あなたは」交流にあなたのスニペットを回す時に私の最高の試みをだ

print "Type 'quit' to quit" 
print "Type 'choices' to see what your choices are" 

current_room = Whiteroom() 
done = False 
while (not done): 
    entry = raw_input("> ") 
    if entry == "quit": 
     done = True 
    if "choices" in entry: 
     current_room.print_choices() 
    if current_room.choices: 
     if entry in current_room.choices:  
      if "white" in entry: 
       current_room = Whiteroom() 

      if "black" in entry: 
       current_room = Blackroom() 

      if "red" in entry: 
       current_room = Redroom() 

      if "green" in entry: 
       current_room = Greenroom() 
       done = True 

      if "blue" in entry: 
       current_room = Blueroom() 

:dが、ゲームを実行するには、この操作を行う必要がありクラスを使用したゲームです。