Seite 1 von 1

Wie kann ich Attribute übergeben?

Verfasst: Samstag 6. Januar 2007, 20:59
von pituran
Hallo

ich habe ein vielleicht zu einfaches Problem für euch.

Ich möchte aus einer Klasse (Zeit), die gleichzeitig in einer anderen Datei (uhrzeit.py) abgespeichert ist Werte (Datum) entnehmen und diese in einer anderen Klassen, die in einer anderen Datei liegt, als Webseite ausgeben.
Ich möchte nicht beides in einer Datei haben!

Datei: webseite.py

Code: Alles auswählen

#-------------------------------------------------
from uhrzeit import*

class Website:

	def __str__(self):
		seite=''' Content-Type: text/html

<html>
	<head>
		<title>test site</title>
	</head>
	<body>
		%s
	</body>
</html>'''  %(Zeit.day, Zeit.month, Zeit.year)

		return seite

print Website()
Datei: uhrzeit

Code: Alles auswählen

#-------------------------------------------------
from time import*

class Zeit:

	def __init__(self):
		self.year = localtime()[0]
		self.month = localtime()[1]
		self.day = localtime()[2]
		self.hour = localtime()[3]
		self.minute = localtime()[4]
		self.second = localtime()[5]

	def pop(self):
		zeit = '''
		%s.%s.%s
''' %(self.day, self.month, self.year)

		return zeit
Ich weiß nicht, warum die Attribute für das Datum nicht übergeben werden?
Wenn ich die Klasse Website ohne die "Zeitwerte" ausgebe, dann wird die Seite im Browser angezeigt.
Versuche ich die Zeit-Klasse einzubinden kommt folgender Fehler:

AttributeError: class Zeit has no attribute 'day'

Das verstehe ich nicht, denn die Klasse "Zeit" ist doch importiert worden nach "webseite.py".

Woran liegt es? Ich sehe es nicht!

Re: Wie kann ich Attribute übergeben?

Verfasst: Samstag 6. Januar 2007, 21:08
von sape
Hi und willkommen im Forum.

Logisch, das die Klasse das Attribut nicht hat. Das ist ja schließlich auch eine Instanz Attribut.

Du musst also erstmal eine Instanz von der Klasse {€dit: Zeit} erzeugen:

Code: Alles auswählen

from uhrzeit import Zeit
diezeit = Zeit()
print diezeit.day
Du kannst aber auch eine Klasse so definieren das die Shared-Member hat:

Code: Alles auswählen

#!/usr/bin/env python
# -*- coding: utf-8 -*-

class Foo(object):
    bar = "blubb"

print Foo.bar
Das bedeutet das alle Instanzen von ``Foo`` sich ``bar`` Teilen und nicht jede Instanz eine eigene Version von ``bar`` hat. Wenn du im Konstruktor ein Attribut erzeugst (like This)...

Code: Alles auswählen

class Foo(object):
    def __init__(self):
        self.bar = "blubb"

print Foo.bar
..ist es klar das eine Exception ausgelöst wird, da es eine Instanzvariablen ist.

EDIT: Korrektur.

Verfasst: Samstag 6. Januar 2007, 21:19
von sape

Code: Alles auswählen

#!/usr/bin/env python
# -*- coding: utf-8 -*-

class Foo(object):
    bar = "blubb 1"
    def __init__(self):
        self.bar2 = "blubb 2"

print Foo.bar # blubb 1

### Logisch, da es ein Instanz Attribut ist.
#print Foo.bar2 # AttributeError: type object 'Foo' has no attribute 'bar2'

###
foo1 = Foo()
foo2 = Foo()

# ``bar`` kriegt nen neune Wert.
Foo.bar = "Foo()"
# Shared-Member. Alle Instanzen teilen sich ``bar``
# Daher kommtr auch bei den folgenden prints immer das gleiche raus.
print foo1.bar 
print foo2.bar

#
foo1.bar2 = "Anderer Wert"
print foo1.bar2 # -> "Anderer Wert"
# hat nicht als wert 'Anderer Wert' , da ``bar2`` ein Instanzattribut ist.
# Das heißt jede Instanz von ``foo`` bekommt ihr eigenes ``bar2``
# und teilt es sich nicht mit den anderen Instanzen.
print foo2.bar2 # -> "blubb 2" 
Ich denke der Unterscheid sollte nun klar sein. Wenn nicht nachfragen.

lg

EDIT: Korrektur.

Verfasst: Sonntag 7. Januar 2007, 12:55
von pituran
Vielen Dank für die nette Aufnahme in dieses Forum und für die schnelle Antwort.

Wenn ich den Rat befolge erhalte ich diese Lösung, die auch wunderbar funktioniert:

Code: Alles auswählen

#-------------------------------------------------
from uhrzeit import*

diezeit = Zeit()

class Website:

	def __str__(self):
		seite=''' Content-Type: text/html

<html>
	<head>
		<title>test site vom %s.%s.%s</title>
	</head>
	<body>
	%s:%s
	</body>
</html>''' %(diezeit.day, diezeit.month, diezeit.year, diezeit.hour, diezeit.minute)

		return seite

print Website()
Abgeshen davon das es so geht, wird diese Programmierung sehr schnell unübersichtlich.
Zum Beispiel kann durch die ständige Verwendung von "%s" das Nachvollziehen von was, wann, wo ausgegeben wird verloren gehen.
Genauso würde sich die Übergabe der Attribute "%(diezeit.day, diezeit.month, ..." in das Unermässliche steigern.

Welche möglichkeiten gäbe es noch, um das ganze übersichtlicher zu gestallten?

Verfasst: Sonntag 7. Januar 2007, 16:14
von BlackJack
Ein Template-System benutzen. Minimale wären `string.Template` oder diese Möglichkeit des Formatierungsoperators:

Code: Alles auswählen

In [14]: '%(name)s the viking' % {'name': 'eric'}
Out[14]: 'eric the viking'
Oder halt ein echtes wie `kid`, `Cheetah` usw.

Wenn Du auf Übersichtlichkeit Wert legst, solltest Du Dir unbedingt "Sternchen-Imports" abgewöhnen.

Verfasst: Sonntag 7. Januar 2007, 18:44
von pituran
Für ernsthaften programmieren ist es natürlich klar, dass ich eines der Frameworks nutzen müste. Aber zum verstehen und ausprobieren wollte ich erstmal so anfangen.

Ich werde es mal mit string.Template probieren und später in die Template-Systeme reinschauen.