Seite 1 von 1

Spiele ohne Klassen

Verfasst: Mittwoch 27. Januar 2016, 17:58
von M&M's_Knabberer
Hab ne Frage:

Ist es möglich mit Python Spielezu Programmieren ohne Klassen zu verwenden?
(Da ich das mit den Klassen nicht verstehe)
In diversen Büchern etc sind die Spiele irgendwie alle mit Klassen erstellt :(

Re: Spiele ohne Klassen

Verfasst: Mittwoch 27. Januar 2016, 18:10
von BlackJack
@M&M's_Knabberer: Jain. Es ist möglich das ohne ``class`` zu machen, aber letztendlich wirst Du wenn es auch nur etwas umfangreicher wird, am Ende doch objektorientiert Schreiben ohne die spezielle Sprachunterstützung zu verwenden, es Dir also unnötig schwieriger machen, oder es wird halt unübersichtlich und fehleranfällig und Du wirst bei der Komplexität schnell an Grenzen stossen.

Wenn das Spiel eine GUI haben soll, dann wird es ohne Klassen wohl auch nicht gehen weil alle gängigen GUI-Rahmenwerke objektorientiert sind. Selbst Pygame wird schnell eklig wenn man seinen Code nicht in eigene Datentypen organisiert oder zum Beispiel von den Klassen im `pygame.sprite`-Modul ableitet.

Re: Spiele ohne Klassen

Verfasst: Mittwoch 27. Januar 2016, 18:14
von M&M's_Knabberer
ok, dann führt wohl kein Weg an den Klassen vorbei..

gibt es einen Weg Klassen irgendwie zu verstehen?^^
Klassen sind das einzige was ich bei Python von den Grundlagen nicht verstanden habe und was auf Klassen aufbaut, Vererbung und was es da sonst noch gibt.

Re: Spiele ohne Klassen

Verfasst: Mittwoch 27. Januar 2016, 18:20
von BlackJack
@M&M's_Knabberer: Da es viele Leute gibt die Klassen verstanden haben, gibt es wohl auch Wege Klassen zu verstehen. ;-)

Re: Spiele ohne Klassen

Verfasst: Mittwoch 27. Januar 2016, 19:11
von noisefloor
Hallo,

_was_ verstehst du denn nicht? Das Grundkonzept ist ja eigentlich relativ simpel.

Ansonsten hat ja jedes brauchbare Tutorial und jedes Python-Buch einsteigerfreundliche Kapitel zu Klassen.

Gruß, noisefloor

Re: Spiele ohne Klassen

Verfasst: Mittwoch 27. Januar 2016, 19:50
von pillmuncher
noisefloor hat geschrieben:_was_ verstehst du denn nicht?
O Mann, wie ich diese Frage schon in der Schule immer gehasst habe...

@M&M's_Knabberer: _was_ verstehst du denn nicht? ;)

Eine Klasse beschreibt einen Datentyp, also eine Menge von Attributen auf Objekten. Zudem ermöglicht eine Klasse, Objekte dieses Datentyps zu erzeugen. Wenn in einer Klasse Foo eine Methode bar() definiert ist, dann kann man diese Methode auf einem Objekt dieses Datentyps aufrufen:

Code: Alles auswählen

In [1]: class Foo:
   ...:     def bar(self):
   ...:         print("hallo")
   ...:         

In [2]: o = Foo()

In [3]: o.bar()
hallo
Interessant wird es allerdings erst, wenn in der Klasse nicht nur Methoden-Attribute, sondern auch Daten-Attribute definiert sind. Diese gibt man im Normalfall beim Erzeugen eines Objektes mit an:

Code: Alles auswählen

class Foo:
    def __init__(self, text):
        self.text = text
    def bar(self):
        print("hallo", self.text)
        

p = Foo("Joe")

p.bar()
hallo Joe

q = Foo("Jim")

q.bar()
hallo Jim
Methoden beschreiben, wie sich Objekte verhalten, in Abhängigkeit von deren Daten-Attributen. Objekte sind also nicht einfach nur Zusammenstellungen von zusammengehörigen Daten. Methoden, deren Verhalten nicht vom Zustand des Objektes abhängen, auf dem sie aufgerufen werden, sollten idR. unabhängige Funktionen sein.

Ich hoffe, dir hilft diese Einleitung ein wenig, wenn du jetzt nochmal dein Tutorial zum Theman Klassen & Objekte durcharbeitest.

Re: Spiele ohne Klassen

Verfasst: Mittwoch 27. Januar 2016, 20:06
von noisefloor
Hallo,
pillmuncher hat geschrieben:
noisefloor hat geschrieben:_was_ verstehst du denn nicht?
O Mann, wie ich diese Frage schon in der Schule immer gehasst habe...
Irgendwann holt dich die Vergangenheit halt immer ein ;-)
Bzw.: Wenn man ein Problem hat, das Problem aber nicht erklären kann, dann hat man zwei Probleme. Was es für die, die Helfen möchten, schwieriger macht.

Was IMHO ja auch immer ein einfaches und nachvollziehbares (und viel benutztes) Beispiel für eine Klasse ist, ist ein (einfaches) Konto. Klassenattribut ist der Betrag auf dem Konto (=Kontostand) , Methoden sind z.B. Abheben, Einzahlen und Kontostand abfragen.

Gruß, noisefloor

Re: Spiele ohne Klassen

Verfasst: Mittwoch 27. Januar 2016, 21:23
von M&M's_Knabberer
Ich verstehe allein schon den Begriff Self nicht.. wofür Steht Self? Und __Init__ und __init_.Self usw.. ??
Ich verstehe das ne Klasse ein Übergeordneter Begriff ist sowas wie Obst, und die unterkategorien der Klasse wären dann zb Bananen,Äpfel, Kirschen etc..
Aber ich finde das in der ANwendung total verwirrend. Klasse xy() dann irgendwie Self dann kommt wohl irgendwie ne Funktion()?? und dann muss immer alles so irgendwie xy.self (warum auch immer versteh garnichts mehr die ganze Logik wird mir nicht klar, vielleicht fehlt meinem Hirn ein paar Vitalstoffe aber irgendwie wirds mir nicht geläufig momentan.)

Re: Spiele ohne Klassen

Verfasst: Mittwoch 27. Januar 2016, 22:00
von BlackJack
@M&M's_Knabberer: `self` ist einfach der Name für das erste Argument einer Methode. Das ist das Objekt auf dem die Methode aufgerufen wurde. Wenn Du ``x['answer']`` und ``x['answer'] = 42`` verstehst, sollte ``x.answer`` und ``x.answer = 42`` eigentlich kein Problem darstellen. Das erste ist wie man bei einem `dict` Werte abfragt und setzt, und das zweite wie man bei einem Objekt Attribute abfragt und setzt. Das ist sehr ähnlich. Die Hauptsächliche ”Magie” bei Klassen/Exemplaren ist das das erste Argument beim Aufruf einer Methode nicht explizit übergeben werden muss, weil dass das automagisch das Objekt ist von dem die Methode ist. Sonst müsste man das ja zwei mal angeben, einmal um an die Methode zu kommen, und dann immer noch mal um es als erstes Argument zu übergeben. Diese ständige Wiederholung kann man sich sparen.

`self` steht also für das Objekt selbst (englisch: „self“). `__init__()` ist der Name der Methode die ausgeführt wird wenn man eine Klasse aufruft und das Objekt dann initialisiert werden muss. Eben durch die `__init__()`-Methode.

Edit: Noch mal zu der Parallele zwischen Wörterbüchern und Objekten mit Attributen: Wenn man kein ``class`` hätte, müsste man verschiedene Werte die veränderbar sind und zusammengehören ja in Wörterbüchern organisieren, die sozusagen den Datenanteil eines Datentyps ausmachen. Und dann hätte man in der Regel verschiedene Funktionen die jeweils auf einer dieser Arten von Datensammlungen Operationen durchführen. Also letztendlich auch objektorientierte Programmierung, nur das Daten und Funktionen nicht syntaktisch zu einer Einheit zusammengefasst werden, sondern nur von der Idee her. Wenn man dann tatsächlich so etwas wie Methoden haben möchte die keine statischen Funktionen sind, sondern von der Datensammlung abhängen, müsste man Funktionen in diese Wörterbücher stecken und wenn man die dann aufrufen will, mit der Datensammlung als Argument, dann fängt es an syntaktisch so umständlich zu werden das man sich eigene Syntax für so etwas wünschen würde. Und genau die gibt es mit Klassen. Also statt ``player['attack'](player, other)`` kann man dann einfach ``player.attack(other)`` schreiben.

Re: Spiele ohne Klassen

Verfasst: Mittwoch 27. Januar 2016, 22:18
von pixewakb
Ansonsten hat ja jedes brauchbare Tutorial und jedes Python-Buch einsteigerfreundliche Kapitel zu Klassen.
Nein, sehe ich nicht so. M. Weigend führt Klassen mit einer Klasse Geld ein, die - ich meine - auch noch Währungen umrechnen kann. Ich habe nichts verstanden. Ich habe es nachher vom Konzept von php verstanden und das war eher Zufall :( Erst von daher habe ich dann mehr über Klassen verstanden und konnte es dann nach und nach anwenden.

Code: Alles auswählen

class Auto(object):

    def __init__(self, geschwindigkeit, insassen):

        self.geschwindigkeit = geschwindigkeit
        self.insassen = insassen

    def get_geschwindigkeit(self):
        return self.geschwindigkeit

    def get_insassen(self):
        """ Liefert die Anzahl der Insassen """
        return self.insassen

    def beschleunigen(self, wert):
        """ beschleunigt den Wagen um Wert km/h"""
        self.geschwindigkeit += wert

    def zusteigen(self, anzahl):
        self.insassen += anzahl

    def aussteigen(self, anzahl):
        self.insassen -= anzahl


if __name__ == "__main__":
    bmw = Auto(0, 2)

    print("Das Auto fährt mit einer Geschwindigkeit von {} km/h".format(bmw.get_geschwindigkeit()))

    print("Es gibt {} Insassen".format(bmw.get_insassen()))

    bmw.zusteigen(3)

    print("Es gibt {} Insassen".format(bmw.get_insassen()))

    bmw.aussteigen(1)    

    print("Es gibt {} Insassen".format(bmw.get_insassen()))

    bmw.beschleunigen(20)

    print("Das Auto fährt mit einer Geschwindigkeit von {} km/h".format(bmw.get_geschwindigkeit())
In der Konsole dann:

Code: Alles auswählen

Das Auto fährt mit einer Geschwindigkeit von 0 km/h
Es gibt 2 Insassen
Es gibt 5 Insassen
Es gibt 4 Insassen
Das Auto fährt mit einer Geschwindigkeit von 20 km/h
Mir hat http://www.peterkropff.de/site/php/oop.htm beim Verständnis des Konzepts sehr (!) geholfen. Was du oben als Klasse siehst, ist übrigens nicht pythonisch (!), d. h. man würde nicht mit solchen getter und setter-Methoden arbeiten, sondern das anders verpacken, aber die Kapitel in deinem Buch (deinen Büchern) werden die Java-typische Art mit Klasse.get_irgendetwas (getter, bekomme etwas zurück) und Klasse.set_irgendetwas (setter, setze einen Wert fest...) verwenden.

PS Stell dir mal vor, du beschleunigst dein Auto mit einer Geschwindigkeit "12" (String!) :D, das ist erkennbar keine Zahl und müsste folglich zu einem Fehler führen. Die Fehlerbehandlung kannst Du in deinen Methoden abwickeln (z. B. Typumwandlung) und dort "verstecken". In der Anwendung bleibt es dann beschleunigen(), bremsen() usw., d. h. die Programmierung ist etwas anspruchsvoller (weniger einsichtig), dafür ist später die Arbeit mit den Klassen und Objekten sehr angenehm.

PPS Stell dir mal vor du hättest eine eigene Klasse "Mensch", dann könntest du dem Auto auch ein Objekt von der Klasse Mensch übergeben. Die Menschen in deinem Auto haben dann die Eigenschaften "Name", "Alter", "Geschlecht" usw. Du kannst dann eine Methode "get_namen_der_insassen()" programmieren, so dass du z. B. in deinem Programm eine Liste der Insassen nach Namen erhältst. Das ist der Punkt, wo m. E. die Freude beginnt, dass der Zugriff plötzlich kinderleicht wird. Das kannst Du sonst nur sehr kompliziert programmieren :)

Ich nutze Python 3.4, d. h. mit Python 2.X könnte es zu Problemen kommen:

Code: Alles auswählen

class Mensch(object):

    def __init__(self, name):
        self.name = name

class Auto(object):

    def __init__(self, insassen):
        self.insassen = insassen

    def get_insassen(self):
        namensliste = []
        for insasse in self.insassen:
            namensliste.append(insasse.name)
        namensliste.sort()
        return namensliste


if __name__ == "__main__":
    luisa = Mensch("Luisa")
    peter = Mensch("Peter")
    sonja = Mensch("Sonja")

    print("Sonja heisst {}.".format(sonja.name))
    
    # Ich übergebe eine Liste mit
    # Objekten der Klasse Mensch!
    vw = Auto([luisa, peter, sonja])
    namensliste = vw.get_insassen()
    
    for name in namensliste:
        print("Im Auto sitzt {}.".format(name))
Spiel mal gedanklich durch, wie du das mit dem normalen Werkzeug programmierst und all das hier ist noch wenig komplex :D Ich mag objektorientierte Programmierung, wenn ich Komplexität in Klassen verpacken kann und dann einen einfachen Zugriff auf die Sachen mittels Methoden habe. (Inzwischen nutze ich auch wieder Funktionen, aber ich mag auch Klassen...)

Re: Spiele ohne Klassen

Verfasst: Mittwoch 27. Januar 2016, 22:54
von BlackJack
Das Beispiel mal ohne Klasse mit einem Wörterbuch und Funktionen (die bis auf die erste eigentlich so etwas wie Prozeduren sind):

Code: Alles auswählen

#!/usr/bin/env python
# coding: utf8
from __future__ import absolute_import, division, print_function


def create_car(seat_count, passenger_count, speed=0):
    result = {
        'seat_count': seat_count,
        'speed': speed,
        'passenger_count': 0,
    }
    add_passengers(result, passenger_count)
    return result


def get_speed(car):
    return car['speed']


def get_passenger_count(car):
    return car['passenger_count']


def accelerate(car, amount):
    car['speed'] += amount


def add_passengers(car, count):
    new_count = car['passenger_count'] + count
    if new_count > car['seat_count']:
        raise ValueError('only {0} seats in the car'.format(car['seat_count']))
    car['passenger_count'] = new_count


def remove_passengers(car, count):
    if count > car['passenger_count']:
        raise ValueError('not enough passengers')
    car['passenger_count'] -= count


def main():
    bmw = create_car(4, 2, 0)
    print(
        'Das Auto fährt mit einer Geschwindigkeit von {} km/h.'.format(
            get_speed(bmw)
        )
    )
    print('Es gibt {0} Insassen.'.format(get_passenger_count(bmw)))
    add_passengers(bmw, 2)
    print('Es gibt {0} Insassen.'.format(get_passenger_count(bmw)))
    remove_passengers(bmw, 1)
    print('Es gibt {0} Insassen.'.format(get_passenger_count(bmw)))
    
    accelerate(bmw, 20)
    print(
        'Das Auto fährt mit einer Geschwindigkeit von {} km/h.'.format(
            get_speed(bmw)
        )
    )


if __name__ == '__main__':
    main()

Re: Spiele ohne Klassen

Verfasst: Donnerstag 28. Januar 2016, 11:16
von noisefloor
Hallo,
pixewakb hat geschrieben:
Nein, sehe ich nicht so. M. Weigend führt Klassen mit einer Klasse Geld ein, die - ich meine - auch noch Währungen umrechnen kann. Ich habe nichts verstanden.
Bleibt trotzdem noch die Frage, ob es an Herr Weigend oder an dir liegt :wink:

Abgesehen davon gibt es in der Tat besser Python-Bücher als seine. Ab das ist ein anderes Thema :-)

Gruß, noisefloor

Re: Spiele ohne Klassen

Verfasst: Donnerstag 28. Januar 2016, 14:53
von pixewakb
Geld ist ein schwieriges Thema und so etwas als Beispiel zu wählen, finde ich grenzwertig. Es liegt nicht an mir.

Was genau würdest Du an Literatur empfehlen!? Wir denken an deutsche Literatur, möglichst umfassend, möglichst wenig Ausschweifungen, d. h. kompakt, verständlich, klar und eingängig <nachtrag>und aktuell (Python 3.x) und höchstens in der letzten Auflage 3, 4 oder 5 Jahre alt</nachtrag>. Im Nachgang würde ich meinen, dass ich die Python Basics vielleicht an einem Abend vermitteln könnte, dafür brauchte Weigend mehr als 100 Seiten.

PS In der Bib konnte ich zwischen dem Openbook oder Weigend wählen. Nachdem ich mir einiges online mit dem OpenBook beigebracht hatte, fiel die Wahl auf Weigend. Das restliche Python-Material war irgendwas zu Version 2.4, 2.5 usw. altertümlich. M. E. sollten Besitzer eines Bibliotheksausweises auch mal häufiger Python-Literatur-Anschaffungswünsche äußern und vor Ort auch ausleihen :wink:

Re: Spiele ohne Klassen

Verfasst: Donnerstag 28. Januar 2016, 15:15
von kbr
pixewakb hat geschrieben:Im Nachgang würde ich meinen, dass ich die Python Basics vielleicht an einem Abend vermitteln könnte
Das mag Dir so vorkommen, da Du die Basics verstanden hast. Aber dieser Eindruck täuscht. Wer das Verständnis noch vor sich hat, braucht dafür länger.

Re: Spiele ohne Klassen

Verfasst: Donnerstag 28. Januar 2016, 15:48
von BlackJack
@pixewakb: Wenn jemand eine Zeichenkette übergibt wo eine Zahl erwartet wird, sollte die Fehlerbehandlung in der Regel nicht darin bestehen den Fehler beim Aufruf auszubügeln, das führt nur zu falschen Erwartungshaltungen. :-)

`get_insassen()` hat einen irreführenden Namen und ist eigentlich ein Einzeiler:

Code: Alles auswählen

# ...
    def get_insassen(self):
        return sorted(mensch.name for mensch in self.insassen)
Wenn man die Basics so schnell verstehen kann, dann mach das doch mal. :twisted: Iteratoren und Funktionen als Werte sind Grundlagen, ebenso wie Generatorausdrücke und Module wie `itertools`.

Was Büchereien angeht da ist man heutzutage ja nicht mehr unbedingt darauf beschränkt was die Bücherei vor Ort besitzt. Oft ist die Bücherei Teil eines Verbunds aus dessen Bestand man sich Bücher bestellen kann, und von den Landes-/Zentralbibliotheken können die auch Bücher anfordern. Kostet in der Regel eine Gebühr, die aber gerade bei Fachliteratur deutlich unter dem Kaufpreis von den Büchern liegt. Falls es sich nicht um die Dorfbibliothek in Hintertupfingen handelt, kann man die Recherche und die Bestellung in der Regel auch Online erledigen.

Re: Spiele ohne Klassen

Verfasst: Donnerstag 28. Januar 2016, 15:51
von bfm
Hallo,

Definition einer Funktion:

Code: Alles auswählen

def addiere(a, b)
    c = a + b
    return c
Über die Argumente a und b werden an die Funktion addiere zwei Werte übergeben. Diese Funktion addiert die zwei Werte und liefert das Ergebnis. Nur wenn der Funktion die Argumente übergeben werden, kann die Funkion mit den Argumenten auch etwas machen. Nur so sind sie der Funktion bekannt. Alles andere drumherum sieht die Funktion nicht und kann auch nicht darauf zugreifen (es gibt ein paar Ausnahmen aber die sollen hier mal Nebensache sein)

Bei den Methoden (Funktionen) eines Objekts (ein Objekt wird oft auch als Klasse bezeichnet) ist es im Prinzip nicht anders. Der Methode wird hier aber nicht nur ein Wert übergeben sondern gleich ein ganzes Objekt nämlich das Objekt "self". Wobei "self" sich innerhalb eines Objektes immer auf sich selber (das Objekt selber) bezieht.

Code: Alles auswählen

class beispiel(object):

    #mit der Methode __init__ wird das Objekt "beispiel" erzeugt. In diesem Fall erbt "beispiel" 
    #von einem Standardobjekt namens "object" des Interpreters (denk nicht drüber nach, es sollte 
    #einfach so gemacht werden. Hier sind wir schon beim Thema Vererbung). 
    #Das Objekt "beispiel" wird innerhalb des Objekts "beispiel" mit "self" angesprochen. Man kann 
    #also auch sagen, innerhalb des Objekts ist "beispiel" = "self".
    #Mit dem Erzeugen des Objekt wird gleichzeitig das "argument1" dem Attribut "self.a" und "argument2" 
    #dem Attribut "self.b" zugeordnet. Das Objekt "beispiel/self" besteht nun aus dem Attributen "self.a" und "self.b"
    
    def __init__(self, argument1, argument2)
        self.a = argument1
        self.b = argument2
        
    #hier wird die Methode "addiere" definiert. Der Methode wird das Objekt "self" 
    #übergeben. An das Objekt "self" sind die Attribute "self.a" und "self.b" gebunden 
    #und die Methode addiere kann die Attribute somit auch verwenden. Würde 
    #man "self" nicht übergeben, dann würde es zu einem Fehler kommen, weil der Methode
    #die Attribute "self.a" und "self.b" nicht bekannt sind. 
    
    def addiere(self)
        ergebnis = self.a + self.b
        return ergebnis

Re: Spiele ohne Klassen

Verfasst: Donnerstag 28. Januar 2016, 16:09
von BlackJack
@bfm: Wobei das jetzt kein gutes Beispiel für eine Klasse ist, denn trotz ``class`` ist das ja immer noch im Grunde eine Funktion. Der typische „code smell“ halt wenn man nur eine `__init__()` und eine einzige weitere öffentliche Methode hat. Dann kann man es ziemlich oft einfach als Funktion schreiben, und das sollte man dann auch machen, denn die Klasse bringt keinen Mehrwert und das ist dann auch keine objektorientierte Programmierung.

Der Satz „ein Objekt wird auch oft als Klasse bezeichnet“ ist falsch. Alles was man in Python an einen Namen binden kann ist ein Objekt, also unter anderem Zahlen, Zeichenketten, Listen, Module, Funktionen, und Klassen. Und davon werden nur Klassen als Klassen bezeichnet. Alles andere wäre verwirrend. :-) Dementsprechend wird in der `__init__()` auch kein Objekt `beispiel` erzeugt, sondern die `__init__()` bekommt ein Objekt vom *Typ* `beispiel` (das bereits erzeugt wurde) und initialsiert dieses. Das `beispiel` und `self` nicht gleich sind, kann man auch ganz einfach prüfen: ``print beispiel == self`` gibt `False` aus. Richtig wäre ``print beispiel == type(self)``.

Re: Spiele ohne Klassen

Verfasst: Donnerstag 28. Januar 2016, 16:10
von noisefloor
Hallo,
Was genau würdest Du an Literatur empfehlen!?
Bei freiesMagazin findest du bergeweise Rezension zu Python-Büchern, ein großer Teil ist von mir geschrieben (also die Rezension, nicht die Bücher ;-) ).

Das beste mir bekannt Python-Buch ist "Fluent Python" - ist aber keine Einsteiger-Literatur.

Ansonsten: ein Buch lesen und parallel "learning by doing". Ich selber haben am meisten gelernt, wenn ich konkret ein Projekt für mich bzw. für den eigenen Nutzen umgesetzt habe. So was ist IMHO wesentlich effektiver als irgendwelche Beispiele nachzuprogrammieren, die einen aber eigentlich gar nicht interessieren.

Und natürlich bei Bedarf hier im Forum posten und sich dann erzählen lassen, was so alles besser gemacht werden kann :-)

Gruß, noisefloor

Re: Spiele ohne Klassen

Verfasst: Donnerstag 28. Januar 2016, 16:23
von BlackJack
@noisefloor: Der Tipp mit dem interessanten Projekt ist gut, aber der OP will Spiele programmieren und kommt mit Büchern nicht klar, die OOP anhand von Spieleprogrammierung erklären.