Wie kann ich Attribute übergeben?

Sockets, TCP/IP, (XML-)RPC und ähnliche Themen gehören in dieses Forum
Antworten
pituran
User
Beiträge: 3
Registriert: Samstag 6. Januar 2007, 20:46

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!
sape
User
Beiträge: 1157
Registriert: Sonntag 3. September 2006, 12:52

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.
Zuletzt geändert von sape am Samstag 6. Januar 2007, 21:29, insgesamt 3-mal geändert.
sape
User
Beiträge: 1157
Registriert: Sonntag 3. September 2006, 12:52

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.
pituran
User
Beiträge: 3
Registriert: Samstag 6. Januar 2007, 20:46

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?
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.
pituran
User
Beiträge: 3
Registriert: Samstag 6. Januar 2007, 20:46

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.
Antworten