Funktionen in Listen speichern

Wenn du dir nicht sicher bist, in welchem der anderen Foren du die Frage stellen sollst, dann bist du hier im Forum für allgemeine Fragen sicher richtig.
Antworten
gnuser
User
Beiträge: 5
Registriert: Donnerstag 27. Januar 2011, 21:14

Hallo,
ich bin grad an einer Übung von A Byte of Python:

Code: Alles auswählen

#! /usr/bin/python

# Klassenstruktur Orig. aus "A byte of Pythond (deu)
class SchulMitglied:
	def __init__(self, name, alter):
		self.name = name
		self.alter = alter
		print 'Schulmitglied "%s" wird initialiesiert' % self.name
	
	def auskunft(self):
		print 'Name: "%s", Alter: "%d"' % (self.name, self.alter)
		
class Lehrer (SchulMitglied):
	def __init__(self, name, alter, gehalt):
		SchulMitglied.__init__(self, name, alter)
		self.gehalt = gehalt
		print 'Lehrer: "%s" inititalisiert' % self.name

	def auskunft(self):
		SchulMitglied.auskunft(self)
		print 'Gehalt: "%d"' % self.gehalt

class Schueler (SchulMitglied):
	def __init__(self, name, alter, note):
		SchulMitglied.__init__(self, name, alter)
		self.note = note
		print 'Schueler: "%s" inititialisiert' % self.note

	def auskunft(self):
		SchulMitglied.auskunft(self)
		print 'Note: "%1.1f"' % self.note

# Da ich noch etwas den Syntax üben wollte, habe ich mich entschlossen, das script interactiver zu machen
fort = True
# Lehrere Listen, in dem die passende Funktion reinsoll
ln = []
sn = []

while fort:
	group = int(raw_input('Sind Sie Lehrer (1) oder Schueler (2)?  '))
	n = str(raw_input('Geben Sie ihren Namen ein:  '))
	a = int(raw_input('Geben Sie ihr Alter ein:  '))
	if group == 1:
		g = int(raw_input('Geben Sie ihr Gehalt ein:  '))
		lno = 'Lehrer(%s, %d, %d).auskunft()' % (n, a, g) # Fertige Funktion sozusagen
		ln.append(lno) # Hinzufügen der fertigen Funktion der Liste, um mehrere Mitglieder zu ermöglichen
	if group == 2:
		no = raw_input('Geben Sie ihre durchschnittliche Note ein:  ')
		sno = 'Schueler(%s, %d, %1,1f).auskunft()' % (n, a, no)
		sn.append(sno)
	
	wei = str(raw_input('Neuer Eintrag?  '))
	if wei == "nein":
		fort = False
#Ausgabe aller Daten
for lehrer in ln:
        print lehrer # Wie zu erwarten, wird ein String ausgegeben...

Was ich nun verbessern möchte ist die Lesbarkeit, welche zwar einfach aber etwas umständlich vorkommt und eben, dass ich die Funktionen ausgeben kann, es muss irgendwie die Funktion mit den parametern als Datentyp "kommando" gespeichert werden.

Gruß
BlackJack

@gnuser: Das sieht sehr Merkwürdig aus was Du da machst. Was Du da speicherst sind keine Funktionen, sondern Zeichenketten. Was Du eigentlich speichern wollen solltest wären Lehrer- und Schüler-Objekte. Und auf denen könntest Du dann nach der Eingabe die Methode(n) aufrufen.

Zur Lesbarkeit würden auch vernünftige Namen beitragen. `ln`, `sn`, `wei`, und `fort` sind nicht wirklich aussagekräftig.

Gründlich getestet hast Du das wohl auch nicht, wenn die ``sno = ...``-Zeile sollte eine Ausnahme auslösen bei der Ausführung.
gnuser
User
Beiträge: 5
Registriert: Donnerstag 27. Januar 2011, 21:14

Das sieht sehr Merkwürdig aus was Du da machst. Was Du da speicherst sind keine Funktionen, sondern Zeichenketten. Was Du eigentlich speichern wollen solltest wären Lehrer- und Schüler-Objekte. Und auf denen könntest Du dann nach der Eingabe die Methode(n) aufrufen.
Das es Strings sind, habe ich ja bereits in der letzten Zeile beschrieben ohne ' ' wird die funktion ja ausgeführt mit ' ' hingeen gespeichert, was dem Ziel doch einem stück näher ist.
Daran habe ich auch schon gedacht, also das man die eingaben n, a,... entweder per dictionary oder per liste speichert und dann per array darauf zugreift

Code: Alles auswählen

n = ['Bernd', 'Guido', 'Detlef', 'Jürgen']
a = [22, 45, 78, 65]
Lehrer(n[0], a[0]).aukunft()
Dies wäre aber ziemlich umständlich irgendwie
Zur Lesbarkeit würden auch vernünftige Namen beitragen. `ln`, `sn`, `wei`, und `fort` sind nicht wirklich aussagekräftig.
stimmt die variablen sind nicht wirklich selbst erklärend z.T. fällt auch nichts direktes ein, da name, alter bereits in benutzung sind.
Trotzdem dachte ich bei lesbarkeit eher über die herangehensweise, also der Weg zum Ziel,
Gründlich getestet hast Du das wohl auch nicht, wenn die ``sno = ...``-Zeile sollte eine Ausnahme auslösen bei der Ausführung.
nur ein kleiner schreibfehler :D


Gruß
Benutzeravatar
Hyperion
Moderator
Beiträge: 7478
Registriert: Freitag 4. August 2006, 14:56
Wohnort: Hamburg
Kontaktdaten:

Funktionen sind in Python auch Objekte!

Code: Alles auswählen

def say_hello(name):
    print "Hello, {0}".format(name)

foo = say_hello
foo("Alfi Hartkor")
Und Objekte von Klassen legst Du so an:

Code: Alles auswählen

class Lehrer(object)
    def __init__(self, vorname, nachname, alter):
        self.vorname = vorname
        self.nachname = nachname
        self.alter = alter

    def auskunft(self):
        print "{0} {1}, Alter: {2}".format(self.vorname, self.nachname, self.alter)

alfi = Lehrer("Alfi", "Hartkor", 36)
# natürlich darf man die Funktion erst nach dem Binden an einen Namen ausführen
alfi.auskunft()
encoding_kapiert = all(verstehen(lesen(info)) for info in (Leonidas Folien, Blog, Folien & Text inkl. Python3, utf-8 everywhere))
assert encoding_kapiert
Benutzeravatar
/me
User
Beiträge: 3556
Registriert: Donnerstag 25. Juni 2009, 14:40
Wohnort: Bonn

gnuser hat geschrieben:Was ich nun verbessern möchte ist die Lesbarkeit, welche zwar einfach aber etwas umständlich vorkommt und eben, dass ich die Funktionen ausgeben kann, es muss irgendwie die Funktion mit den parametern als Datentyp "kommando" gespeichert werden.
Entweder habe ich hier ein Verständnisproblem was du überhaupt erreichen willst oder du hast ein Verständnisproblem bezüglich Objekten und Klassen.

Warum möchtest du hier eine Funktion speichern? Was stellst du dir überhaupt unter "Funktion speichern" vor?

Klassen sind kein Selbstzweck. Klassen sind (etwas vereinfacht gesagt) dazu da, dass man eine bzw. mehrere Instanzen davon erstellt und darüber dann ihre Methoden aufruft. Sinnvoller wäre es daher sicher, wenn du eine komplette Instanz deines Lehrer-Objekts in die Liste aufnimmst und beim späteren Durchlaufen die entsprechende Methode aufrufst.
gnuser
User
Beiträge: 5
Registriert: Donnerstag 27. Januar 2011, 21:14

@Hyperion, danke genau das habe ich gesucht, gibt es eine Seite, die diese Art von Formatierung genauer erläutert?
Sieht mir bis jetzt etwas "unpythonisch" aus von dem Syntax-Stil her (als wäre es nachträglich von C oder ähnlichen übernommen worden)

@me
Klassen sind (etwas vereinfacht gesagt) dazu da, dass man eine bzw. mehrere Instanzen davon erstellt und darüber dann ihre Methoden aufruft. Sinnvoller wäre es daher sicher, wenn du eine komplette Instanz deines Lehrer-Objekts in die Liste aufnimmst und beim späteren Durchlaufen die entsprechende Methode aufrufst.
Was meinst du damit jetzt genau?

Gruß
Benutzeravatar
Hyperion
Moderator
Beiträge: 7478
Registriert: Freitag 4. August 2006, 14:56
Wohnort: Hamburg
Kontaktdaten:

gnuser hat geschrieben:@Hyperion, danke genau das habe ich gesucht, gibt es eine Seite, die diese Art von Formatierung genauer erläutert?
Was meinst Du mit Formatierung?
gnuser hat geschrieben: Sieht mir bis jetzt etwas "unpythonisch" aus von dem Syntax-Stil her (als wäre es nachträglich von C oder ähnlichen übernommen worden)
Inwiefern? Was genau meinst Du... ich habe ja mehrere Zeilen Code gepostet!

Zu den Klassen:
Wenn man mehrere Objekte verwalten möchte, so bietet einem Python dafür grundlegende Datenstrukturen, wie etwa Listen Dictionaries usw. In diese packst Du einfach Objekte rein. Ob es sich dabei um simple Sachen wie Strings, Integer, usw. handelt, oder aber um Instanzen von (eigenen) Klassen oder gar Funktionen spielt doch dabei keine Rolle.

Nehmen wir wieder ein Personen Beispiel:

Code: Alles auswählen

In [1]: class Person(object):
   ...:     def __init__(self, name):
   ...:         self.name = name
   ...:
   ...:

In [2]: persons = []

In [3]: persons.append(Person("Christian"))

In [4]: persons.append(Person("Alfi"))

In [5]: persons
Out[5]:
[<__main__.Person object at 0x01063730>,
 <__main__.Person object at 0x01063930>]

In [7]: persons[0]
Out[7]: <__main__.Person object at 0x01063730>

In [8]: persons[0].name
Out[8]: 'Christian'
encoding_kapiert = all(verstehen(lesen(info)) for info in (Leonidas Folien, Blog, Folien & Text inkl. Python3, utf-8 everywhere))
assert encoding_kapiert
derdon
User
Beiträge: 1316
Registriert: Freitag 24. Oktober 2008, 14:32

Hyperion: Er meint das String-Formatting, das in Python seit 2.6 mittels str.format funktioniert.

gnuser: Advanced String Formatting,
gnuser
User
Beiträge: 5
Registriert: Donnerstag 27. Januar 2011, 21:14

@Hyperion

Code: Alles auswählen

"{0} {1}, Alter: {2}"
Nun ja auch wenn ich Python erst kurze Zeit benutze/lerne, sieht man ja bei einer Programmiersprache immer einen stil, da ja die Person, welche die Sprache entwickelt hat, seinen Stil pflegt bzw. nur dessen stil einfliesst.
und "{0} {1}, Alter: {2}" kam mir da etwas anders vor, als man es erstmal von Python gewohnt ist, welches ja zum größten teil auf module aufbaut.

@derdon
Genau das meinte ich, sehe ich das richtig, dass es sich jediglich um "den Nachfolger" von

Code: Alles auswählen

print  'Hallo %s, heute ist der %d. %s' % (name, tag, monat)
handelt?


Da ich noch am Anfang bin, wollte ich fragen, ob es noch eine Seite gibt, welche Übungsaufgaben bereitstellt, welche man dann löst und per spoiler ansehen kann


Gruß
derdon
User
Beiträge: 1316
Registriert: Freitag 24. Oktober 2008, 14:32

gnuser hat geschrieben:@derdon
Genau das meinte ich, sehe ich das richtig, dass es sich jediglich um "den Nachfolger" von

Code: Alles auswählen

print  'Hallo %s, heute ist der %d. %s' % (name, tag, monat)
handelt?
Ja, so kann man das sehen. Wobei nicht einfach nur die Syntax geändert wurde; die neue Methode ist auch mächtiger und ermöglicht mehr Arten von Formatierungen. Einfach die Beispiele in der Doku anschauen.
Benutzeravatar
/me
User
Beiträge: 3556
Registriert: Donnerstag 25. Juni 2009, 14:40
Wohnort: Bonn

gnuser hat geschrieben:
Klassen sind (etwas vereinfacht gesagt) dazu da, dass man eine bzw. mehrere Instanzen davon erstellt und darüber dann ihre Methoden aufruft. Sinnvoller wäre es daher sicher, wenn du eine komplette Instanz deines Lehrer-Objekts in die Liste aufnimmst und beim späteren Durchlaufen die entsprechende Methode aufrufst.
Was meinst du damit jetzt genau?

Code: Alles auswählen

class Person():
    def __init__(self, first_name, last_name):
        self.first_name = first_name
        self.last_name = last_name
        
    def full_name(self):
        return '{0} {1}'.format(self.first_name, self.last_name)
    
people = []
eric = Person('Eric', 'Idle')
people.append(eric)
people.append(Person('Graham', 'Chapman'))
people.append(Person('John', 'Cleese'))
for person in people:
    print person.full_name()
gnuser
User
Beiträge: 5
Registriert: Donnerstag 27. Januar 2011, 21:14

ah ok, danke
melde mich dann, wenn es wieder probleme geben sollte

gruß
Antworten