Eigenschaft scheint nicht zu existieren

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
agol
User
Beiträge: 2
Registriert: Montag 23. Juni 2008, 08:50

Hallo,
ich hatte mir vorgenommen zur Übung ein kleines Textadventure zu schreiben, muss aber leider schon ganz am Anfang verzweifeln.
Ich habe Gegenstände die natürlich Eigenschaften wie den Namen oder eine Beschreibung haben und von einer Klasse Gegenstand vererben. Leider klappt schon das Ausgeben dieser Eigenschaften zu Test nicht :(. Python sagt sie würden gar nicht existieren:
Traceback (most recent call last):
File "gegenstand.py", line 68, in ?
print Vase().GetBeschreibung()
File "gegenstand.py", line 20, in GetBeschreibung
return self.__Beschreibung
AttributeError: 'Vase' object has no attribute '_Gegenstand__Beschreibung

Da ich ziemlicher Python- und Programmieranfänger bin weiß ich da leider überhaupt nicht weiter.
Wisst ihr vielleicht, was da los ist?

hier der code:

Code: Alles auswählen

###imports###
import copy
##########
###die zusätzlich definierten Ausnahmen###
class SetExecption(Exception):
	pass
#############################

###Oberklasse für alle Gegenstände###
class Gegenstand(object):
	def __init__(self):
		self.__Name = 'Gegenstand'
		self.__Beschreibung = 'Beschreibung'
		self.__KannEnthalten = {} #Objekte die enthalten sein dürfen
		self.__Inhalt = {}	#was drin ist, Keys sind die Namen, Values die Objekte
	###Schnittstelle###
	def GetName(self):
		return self.__Name
	def GetBeschreibung(self):
		return self.__Beschreibung
	def GetKannEnthalten(self):
		return copy.copy(self.__KannEnthalten)
	def GetInhalt(self):
		return copy.copy(self.__Inhalt)
	
	def SetInhalt(self,inhalt):
		#wenn alle Objekte aus inhalt enthalten sein sein dürfen
		#wird zugewiesen
		if  [x for x in inhalt.keys() if x in self.GetKannEnthalten.keys()] != inhalt: # x ist ein gegenstand
			raise SetExeption
		else:
			self.__Inhalt = inhalt
	def Dazu(self,gegenstandsstring):
		self.SetInhalt[gegenstandsstring] = self.GetKannEnthalten(gegenstandsstring)()

###Klassen der Gegenstände###########
class Blume(Gegenstand):
	def __init__(self):
		self.__Name = 'Blume'
		self.__Beschreibung = 'Eine herrliche Blume!'
		self.__KannEnthalten = {}
		self.__Inhalt = {}

class Vase(Gegenstand):
	def __init__(self):
		self.__Name = 'Vase'
		self.__Beschreibung = 'Eine schoen anzusehende Vase'
		self.__KannEnthalten = {'Blume':Blume}
		self.__Inhalt = {}
class Tisch(Gegenstand):
	def __init__(self):
		self.__Name = 'Tische'
		self.__Beschreibung = 'Eine flacher Tisch.'
		self.__KannEnthalten = {Vase:'Vase','Blume':Blume}

class Raum:
	def __init__(self,objekte,ausgaenge,beschreibung=''): #obekte sei Dictionary
		self.__objekte = objekte
		self.__ausgaenge = {'rechts':None,'links':None,vorne:None,hinten:None}
		self.__beschreibung = beschreibung
	def ausgabe(self):
		S = '' #hier kommen die Objekte im raum rein
		for schluessel in Objekte:
			S = S + schluessel
		return "Ein Raum mit folgenden Gegenständen darin %s \n %s" % (S,Beschreibung)
#####################################

print Vase().GetBeschreibung()
Zuletzt geändert von agol am Montag 23. Juni 2008, 11:45, insgesamt 2-mal geändert.
Benutzeravatar
Hyperion
Moderator
Beiträge: 7478
Registriert: Freitag 4. August 2006, 14:56
Wohnort: Hamburg
Kontaktdaten:

Hallo agol,

Herzlich willkommen im Python-Forum!

Zunächst einmal eine kleine Anmerkung: Du kannst Bei Pasten von Code das code-tag verwenden, bei Python-Code sogar so:

Code: Alles auswählen

[ code=Python ]
Zu Deinem Problem: Lies Dir noch mal das Kapitel über "Private Variables" im Tutorial durch! (Kurztipp: Lass sie weg!)

Zu Deinem Code: Versuche Dich mehr nach PEP8 zu richten. So liest sich Dein Code sehr schlecht. generell scheinst Du von Java her zu kommen? (http://www.python.org/dev/peps/pep-0008/)

Die ganzen Getter-Methoden sind in Python eher unüblich und auch nicht notwendig; Du nutzt sie ja nur, weil Du Attribute "private" gestalten willst. Nur ist das in den wenigsten Fällen wirklich sinnvoll.

So, ich hoffe das hilft Dir ein wenig weiter :-)
Pekh
User
Beiträge: 482
Registriert: Donnerstag 22. Mai 2008, 09:09

Wenn du die ganzen doppelten Unterstriche entfernst, sollte es laufen. Die Dinger werden üblicherweise nur in ganz ganz seltenen Ausnahmefällen verwendet. Und dann solltest du auch genau wissen, was du da tust (siehe Doku).

Eigenschaften von Objekten mit gettern und settern zu kapseln gilt als unpythonisch. In Java und C++ ist das eine gängige Praxis, in Python nicht (und wenn dann doch eher nur mit einem (führenden!) Unterstrich.
agol
User
Beiträge: 2
Registriert: Montag 23. Juni 2008, 08:50

Aber wenn irgendwas überprüft werden soll, bevor einem Attribut ein neuer Wert zugewiesen wird, wie mach ich das dann am besten ohne Setter-Methode?

PS: hab jetzt

Code: Alles auswählen

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

Naja, das geht natürlich nur über eine Art Setter-Methode!
BlackJack

Dazu bitte die Doku zur `property()`-Funktion lesen. Das ist nämlich der Grund, warum man bei Java sicherhaltshalber zu jedem popeligen, eigentlich öffentlichen Attribut einen trivialen Getter und Setter schreibt. Bei Python braucht man das nur bei denen zu machen, bei denen man wirklich etwas zusätzlich zur Zuweisung oder Abfrage machen will.
Antworten