Python - Klassen und OOP-Grundlagen

Ich verstehe den Unterricht nicht ganz. Ich habe die Python-Dokumentation und einige andere Tutorials gelesen. Ich verstehe das Wesentliche, verstehe aber die Nuance nicht. Zum Beispiel in meinem Code hier:

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

(OriginalCodepad)

Ich möchte das Klassenweißzimmer zurückgeben. Was entweder nicht möglich ist oder nicht richtig gemacht wird. Wenn Sie klären könnten, wie Sie eine Klasse zurückgeben oder wie Sie zwei Klassen miteinander "verknüpfen", so dass die Whiteroom-Wiederholungen für das else und die anderen Räume (die Klassen wären) zurückgegeben werden, wenn sie aufgerufen werden, wäre das großartig.

Auch ich bin super wackelig auf__init__ und bin mir immer noch nicht ganz sicher, wozu es gut ist. Jeder sagt mir immer wieder, dass es "initialisiert", was ich mir sicher bin, aber das scheint meinem Gehirn nicht zu helfen.

Antworten auf die Frage(5)

altsam sein. Der einzige Weg, um es wirklich durchzugehen, besteht darin, sich die Zeit zu nehmen, viel zu lesen und zu üben. Ein guter Anfang wäre hier.http://www.voidspace.org.uk/python/articles/OOP.shtml undhttp://wiki.python.org/moin/BeginnersGuide/Programmers

Lösung für das Problem

eine Funktion übernommen und nur die geändertdef zuclass. Ich vermute, dassmeistens funktioniert in deinem Fall, aber es ist nicht so, wie der Unterricht verlaufen soll.

Klassen enthalten Funktionen (Methoden) und Daten. Zum Beispiel hast du einen Ball:

<code>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])
</code>

Jetzt haben wir eineBall Klasse. Wie können wir es benutzen?

<code>>>> ball1 = Ball()
>>> ball1
<Ball object at ...>
</code>

Es sieht nicht sehr nützlich aus. Die Daten sind dort, wo es nützlich sein könnte:

<code>>>> ball1.position
(100, 100)
>>> ball1.velocity
(0, 0)
>>> ball1.position = (200, 100)
>>> ball1.position
(200, 100)
</code>

Okay, cool, aber was ist der Vorteil gegenüber einer globalen Variablen? Wenn Sie einen anderen habenBall Beispielsweise bleibt es unabhängig:

<code>>>> ball2 = Ball()
>>> ball2.velocity = (5, 10)
>>> ball2.position
(100, 100)
>>> ball2.velocity
(5, 10)
</code>

Undball1 bleibt unabhängig:

<code>>>> ball1.velocity
(0, 0)
</code>

Was ist nun damit?bounce Methode (Funktion in einer Klasse), die wir definiert haben?

<code>>>> ball2.bounce()
>>> ball2.velocity
(5, -10)
</code>

Dasbounce Methode veranlasste es, die zu ändernvelocity Daten von sich. Nochmal,ball1 wurde nicht angerührt:

<code>>>> ball1.velocity
</code>
Anwendung

Ein Ball ist ordentlich, aber die meisten Leute simulieren das nicht. Du machst ein Spiel. Überlegen wir uns, was für Dinge wir haben:

Ein Zimmer ist das offensichtlichste, was wir haben könnten.

Also lasst uns ein Zimmer machen. Räume haben Namen, also werden wir einige Daten haben, um das zu speichern:

<code>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.
</code>

Und lassen Sie uns eine Instanz davon machen:

<code>>>> white_room = Room("White Room")
>>> white_room.name
'White Room'
</code>

Schick. Dies stellt sich jedoch als nicht allzu nützlich heraus, wenn Sie möchten, dass verschiedene Räume unterschiedliche Funktionen habenUnterklasse. EINUnterklasse erbt alle Funktionen von seinerSuperklasseSie können jedoch weitere Funktionen hinzufügen oder die Funktionen der Superklasse überschreiben.

Überlegen wir uns, was wir mit Räumen machen wollen:

Wir wollen mit Räumen interagieren.

Und wie machen wir das?

Der Benutzer gibt eine Textzeile ein, auf die geantwortet wird.

Wie darauf reagiert wird, hängt vom Raum ab. Lassen Sie uns also den Raum mit einer aufgerufenen Methode behandelninteract:

<code>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!"
</code>

Versuchen wir nun, damit zu interagieren:

<code>>>> 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!
</code>

Ihr ursprüngliches Beispiel war das Wechseln zwischen Räumen. Verwenden wir eine globale Variable namenscurrent_room zu verfolgen, in welchem ​​Raum wir sind.1 Machen wir auch einen roten Raum.

1. Neben globalen Variablen gibt es hier bessere Optionen, aber ich werde der Einfachheit halber eine verwenden.

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

Versuchen wir das jetzt mal:

<code>>>> red_room = RedRoom()
>>> current_room = red_room
>>> current_room.name
'Red Room'
>>> current_room.interact('go to white room')
>>> current_room.name
'White Room'
</code>

Übung für den Leser: Code hinzufügen zuWhiteRoom'sinteract das erlaubt dir, in den roten Raum zurückzukehren.

Jetzt, da wir alles haben, lassen Sie uns alles zusammenfügen. Mit unserem neuenname Daten zu allen Räumen können wir auch den aktuellen Raum in der Eingabeaufforderung anzeigen!

<code>def play_game():
    global current_room
    while True:
        line = raw_input(current_room.name + '> ')
        current_room.interact(line)
</code>

Möglicherweise möchten Sie auch eine Funktion zum Zurücksetzen des Spiels ausführen:

<code>def reset_game():
    global current_room, white_room, red_room
    white_room = WhiteRoom()
    red_room = RedRoom()
    current_room = white_room
</code>

Fügen Sie alle Klassendefinitionen und diese Funktionen in eine Datei ein, und spielen Sie sie an der Eingabeaufforderung wie folgt ab (vorausgesetzt, sie befinden sich inmygame.py):

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

Um das Spiel zu spielen, indem Sie das Python-Skript ausführen, können Sie dies unten hinzufügen:

<code>def main():
    reset_game()
    play_game()

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

Und das ist eine grundlegende Einführung in den Unterricht und wie Sie sie auf Ihre Situation anwenden können.

 Niklas B.05. Apr. 2012, 06:13
@icktoofay: Ja, ich denke du hast einen Punkt :) +1 für eine lange und sehr detaillierte Erklärung.
 Colton Allen04. Apr. 2012, 22:21
Egal, ich habe es herausgefunden! Danke nochmal für deine Hilfe :)
 Niklas B.04. Apr. 2012, 16:55
DasBall sollte keine Klasse sein. Faustregel: Wenn es nur zwei Methoden gibt, von denen eine ist__init__, sollten Sie eine Funktion und verwendenfunctools.partial um die Funktion an einige Daten zu binden. Gleiches gilt für die anderen hier vorgestellten Klassen. Python ist nicht Java! Das einzige was ich hier sehe ist dassollte Ist das Spiel selbst eine Klasse, für die Sie stattdessen den modul-globalen Status verwenden?
 icktoofay05. Apr. 2012, 06:11
@ Niklas: Ja; der Spielzustand wirklichsollte sei in einer Klasse; Ich habe jedoch versucht, es so einfach wie möglich zu gestalten, und ich hatte das Gefühl, dass die Einstufung des Spielzustands in eine Klasse meine Antwort verwirrender machen könnte. Zweitens sollten einige dieser Dinge vielleicht keine Klassen sein, aber da ich versucht habe, die Verwendung von Klassen zu demonstrieren, halte ich es für angemessen, sie zu verwenden. Außerdem denke ich, dass sich jemand andere Methoden und Daten überlegen könnte, um sie zu den Klassen hinzuzufügen.
 Colton Allen04. Apr. 2012, 22:14
In der Benutzerübung habe ich versucht, den Übergang vom weißen zum roten Raum zu ermöglichen. Aber ich kann nicht. Ich habe "if" x "in folgende Zeile eingefügt: current_room = red_room" Die aktuelle Raumvariable ändert sich nicht. Allerdings, wenn ich etwas mache wie: "wenn" x "in Zeile: print" this "" es funktioniert. Vielen Dank für Ihren Beitrag. Es war super hilfreich!

Tut mir leid, das zu sagen, aber das ist kaum zu retten.

Soweit ich Ihnen sagen kann, möchten Sie so etwas wie eine Raumklasse, zum Beispiel:

<code>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"
</code>

Dann können Sie einen bestimmten Raum wie den Whiteroom so gestalten:

<code>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."
</code>

Dann müsstest du folgendes tun, um das Spiel zu starten:

<code>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()
</code>

Das ist mein bester Versuch, dein Snippet mithilfe von Klassen in ein tatsächliches Spiel zu verwandeln.

dass Sie das alles schon einmal gehört haben, aber ich werde es versuchen.

Klassen sind eine Möglichkeit, eine Reihe von Funktionen und Variablen zu einem einzigen Objekt zusammenzufassen. Wenn Sie den ganzen Weg dahin zurücklegen, ist dies einfach eine Möglichkeit, alles in sinnvollen Gruppen zu organisieren. Es gibt Vorteile für das Verständnis, Debuggen, Erweitern oder Warten von Dingen, aber im Grunde ist es nur eine Möglichkeit, etwas in Ihrem mentalen Modell klarer zu definieren.

Ihr Code sieht so aus, als würden Sie versuchen, Ihr gesamtes Programm in ein 'Objekt' zu schreiben (tatsächlich haben Sie nur eine falsch geschriebene Funktion).

Betrachten Sie dies stattdessen.

Denken Sie an Ihr mentales Modell von Räumen mit Türen und Whiteboards. Türen haben eine Farbe. Auf Whiteboards kann auch Text geschrieben werden. Wir werden es dort belassen, um einfach zu sein.

Für mich sind dies 3 verschiedene Objekte - ein Türobjekt mit einer Zeichenfolge für Farbe, ein Whiteboard-Objekt mit einer Zeichenfolge für den Text und ein Raumobjekt mit einer Tür und einer Whiteboard.

Betrachten Sie den folgenden Code:

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

Dasdrin function wird aufgerufen, wenn Sie eine neue Instanz Ihrer Klasse 'initialisieren'. Im Beispiel mache ich 3 Raumobjekte, von denen jedes intern ein Tür- und ein Whiteboard-Objekt erzeugt. Die Parameter übergebe ich in den KonstruktorRoom(parameter1, parameter2) werden an den übergebendrin Funktionen - Sie können sehen, dass ich hiermit die Türfarbe und optional Text auf dem Whiteboard einstelle. Beachten Sie auch, dass auf die Variablen, die zu den Objekten gehören, verwiesen wirdself - Diese Referenz wird als erster Parameter an alle Klassenfunktionen übergeben (und wird später wichtiger, wenn Sie Klassen und andere fortgeschrittenere Dinge erweitern).

Python lernen von Mark Lutz. Es ist eine umfassende Quelle zum Verständnis von Python-Konzepten, insbesondere zum Codieren vonPythonic Weg.

Als Online-Referenz gefallen mir die Tutorials vondiese Seite? ˅. Geh das durchPost, es wird dir bei init helfen. OOPs in Python sind sehr einfach zu verstehen und zu implementieren. Es scheint zunächst entmutigend, aber es ist ein Kinderspiel, nachdem Sie einige grundlegende OOP-Codes programmiert haben. Gerne lernen..

Ihre Antwort auf die Frage