Ist dieses Vorgehen richtig?

Sockets, TCP/IP, (XML-)RPC und ähnliche Themen gehören in dieses Forum
Antworten
Stolzi
User
Beiträge: 155
Registriert: Mittwoch 18. August 2004, 15:44

Hallo,
ich hatte folgendes Problem:

Code: Alles auswählen

def _any_page(req, name):
	template=psp.PSP(req, 'templates/kopf.html')
	template=template + psp.PSP(req, name)
	template=template + psp.PSP(req, 'templates/fuss.html')
	return template
Hier meinte der Publisher Handler:
TypeError: unsupported operand type(s) for +: 'instance' and 'instance'

Daraufhin machte ich es so und es funktioniert:

Code: Alles auswählen

def _any_page(req, name):
	template=psp.PSP(req, 'templates/kopf.html')
	template=str(template) + str(psp.PSP(req, name))
	template=str(template) + str(psp.PSP(req, 'templates/fuss.html'))
	return template
Nur frage ich mich ob dieses Vorgehen korrekt ist? Sollte man es vielleicht anders lösen?
Danke
Stolzi
Dookie
Python-Forum Veteran
Beiträge: 2010
Registriert: Freitag 11. Oktober 2002, 18:00
Wohnort: Salzburg
Kontaktdaten:

Hi Stolzi,

was is psp?
Oder mach mal in der Console pydoc psp.PSP, dann bekommst Du die Attribute und Methoden von psp.PSP angezeigt und kannst Dir anschauen was zum Verbinden von templates vorgesehen ist.


Gruß

Dookie
[code]#!/usr/bin/env python
import this[/code]
Stolzi
User
Beiträge: 155
Registriert: Mittwoch 18. August 2004, 15:44

Hallo Dookie,
psp:
http://www.modpython.org/live/current/d ... i-psp.html
The psp module provides a way to convert text documents (including, but not limited to HTML documents) containing Python code embedded in special brackets into pure Python code suitable for execution within a mod_python handler, thereby providing a versatile mechanism for delivering dynamic content in a style similar to ASP, JSP and others.
stolzi@stefan:~> pydoc psp.PSP
no Python documentation found for 'psp.PSP'

Ich habe eigentlich gefragt obwohls funktioniert weil ichs nicht ganz verstanden habe.

Code: Alles auswählen

def _any_page(req, name):
	template=psp.PSP(req, 'templates/kopf.html')
	return template
funktioniert nämlich, obwohl psp.PSP keinen String zurückgibt.
Jetzt habe ich nicht verstanden was dann die Fehlermeldung
TypeError: unsupported operand type(s) for +: 'instance' and 'instance'
soll?
Dookie
Python-Forum Veteran
Beiträge: 2010
Registriert: Freitag 11. Oktober 2002, 18:00
Wohnort: Salzburg
Kontaktdaten:

Aha.

na psp.PSP Objekte sind nicht dafür da zusammengefügt zu werden. Das machst Du dann am besten so:

Code: Alles auswählen

def _any_page(req, name):
    head = file('templates/kopf.html','r').read()
    body = file(name, 'r').read()
    tail = file('templates/fuss.html','r').read()
    template=psp.PSP(req, string=head+body+tail)
    return template
Oder wenn Du mit einer Klasse arbeitest:

Code: Alles auswählen

class any_page:

    head = file('templates/kopf.html','r').read()
    tail = file('templates/fuss.html','r').read()

    def _any_page(self, req, name):
        body = file(name, 'r').read()
        template=psp.PSP(req, string=self.head+body+self.tail)
        return template
hier werden kopf und fuss Klassenattributen zugewiesen und beim Aufruf der Methode _any_page mit dem body in der Datei "name" zusammengesetzt.
Aber irgendwie scheint mir das ganze psp vom Codedesign her etwas seltsam zu sein.


Gruß

Dookie[/python]
Zuletzt geändert von Dookie am Sonntag 29. August 2004, 14:33, insgesamt 1-mal geändert.
[code]#!/usr/bin/env python
import this[/code]
Stolzi
User
Beiträge: 155
Registriert: Mittwoch 18. August 2004, 15:44

Oh danke! Da wär ich bei der Doku nicht drauf gekommen, dass ich das so verwenden kann!
Kannst du viell noch begründen warum meine Variante überhaupt funktioniert hat und warum sie nicht so gut ist?
normal wird das denke ich sowieso anders gemacht. ich kann das nur in meinem speziellen Fall nicht so machen.
Normal hätte ich eine Datei sowieso.html für Kopf und Fuss in der für den body <%=body%> vorkommt. Dann macht ich es so:

Code: Alles auswählen

def _any_page(req, name):
    sowieso = 'sowieso.html'
    vars = {"body": psp.PSP(req, body.html)}
    return psp.PSP(req, sowieso , vars=vars)
*g* Warum findest du das Codedesign seltsam?
Dookie
Python-Forum Veteran
Beiträge: 2010
Registriert: Freitag 11. Oktober 2002, 18:00
Wohnort: Salzburg
Kontaktdaten:

Funktioniert hat sie, weil das von PSP zurückgegebene Objekt eine Methode __str__ hat die den Pythoncode als String zurückgibt. Ich hab auch lieber getrennte Templates für Kopf und Fuss, daher finde ich daß das leicht in der PSP-Klasse eingebaut werden hätte können, indem getestet wird ob ein File oder eine Liste mit Files übergeben wurde und dann gegebenenfalls in PSP die Templates zusammengefügt werden.

Du kannst aber auch eine site.html machen mit dem Inhalt

Code: Alles auswählen

<%=head%>
<%=body%>
<%=tail%>

Code: Alles auswählen

def _any_page(req, name):
    site = 'templates/site.html'
    vars = {"body" : psp.PSP(req, name),
            "head" : psp.PSP(req, "templates/kopf.html"),
            "tail" : psp.PSP(req, "templates/fuss.html")}
    return psp.PSP(req, site , vars=vars) 

Gruß

Dookie
[code]#!/usr/bin/env python
import this[/code]
Stolzi
User
Beiträge: 155
Registriert: Mittwoch 18. August 2004, 15:44

Mhm, gute Idee. Danke
Aber für mich ist noch die frage offen warum du mein vorgehen mit str() nicht bevorzugt hättest.
Hmm, da komm ich jetzt nicht ganz mit. Und zwar warum es funktioniert wenn ich in der Funktion das Objekt PSP an return übergebe (return psp.PSP(req, site , vars=vars) ). Warum wird da dann schön der String zurückgegeben?
Danke
Stolzi
Dookie
Python-Forum Veteran
Beiträge: 2010
Registriert: Freitag 11. Oktober 2002, 18:00
Wohnort: Salzburg
Kontaktdaten:

von psp.PSP wird kein string zurückgegeben, sondern ein Objekt der Klasse PSP. Das hat warscheinlich einige Eigenschaften um mit anderen Objekten zu arbeiten, bzw. von anderen Objekten, aus modpython, verarbeitet zu werden.

Irgendwie Objekte hin- und herkonvertieren bis es funktioniert und man weiss nicht warum, ist IMHO, kein guter Programmierstiel. Besser ist immer mit den zurückgelieferten Objekten aus Methoden oder Funktionen zu arbeiten wie sie sind und wie es vorgesehen ist.
Ich denke mal, die Entwickler von dem PSP hatten wohl auch meine letzte Variante vorgesehen, um mehrere Templates zu kombinieren.


Gruß

Dookie
[code]#!/usr/bin/env python
import this[/code]
Stolzi
User
Beiträge: 155
Registriert: Mittwoch 18. August 2004, 15:44

Ok danke. Und das?
Hmm, da komm ich jetzt nicht ganz mit. Und zwar warum es funktioniert wenn ich in der Funktion das Objekt PSP an return übergebe (in deinem Beispiel zB: return psp.PSP(req, site , vars=vars) ). Warum wird da dann schön der String zurückgegeben?
Dookie
Python-Forum Veteran
Beiträge: 2010
Registriert: Freitag 11. Oktober 2002, 18:00
Wohnort: Salzburg
Kontaktdaten:

auch da wird kein String zurückgegeben, wenn du das PSP-Objekt aber z.B. mit print ausgibst, wird es von print in einen String umgewandelt.

Dookie
[code]#!/usr/bin/env python
import this[/code]
Milan
User
Beiträge: 1078
Registriert: Mittwoch 16. Oktober 2002, 20:52

Hi. Jepp, denn print könnte man so definieren:

Code: Alles auswählen

import sys
def my_print(irgendwas,fileobj=sys.stdout):
    fileobj.write(str(irgendwas))
    fileobj.write("\n")

print 5
my_print(5)
#jetzt woanders hin
import StringIO
s1=StringIO.StringIO()
s2=StringIO.StringIO()
print >> s1,5
my_print(5,s2)

my_print(s1.getvalue()==s2.getvalue())
Danke übringens für das Modul PSP, hab gar nicht gewusst, dass es sowas gibt. Das muss ich mir mal näher anschauen, wenn ich Zeit habe.
Stolzi
User
Beiträge: 155
Registriert: Mittwoch 18. August 2004, 15:44

Ahaaa, danke euch zweien! habt mich wieder ein kleines bischen schlauer gemacht ;-)
Ich vermute dann mal dass der Publisher Handler die Rückgabe der Funktion mit req.write() ausgibt und das wird vermutlich das ganze genauso wie print in einen String verwandeln.
raist1314
User
Beiträge: 52
Registriert: Dienstag 21. September 2004, 06:58
Wohnort: Adelzhausen
Kontaktdaten:

Ich an deiner Stelle würde statt psp lieber Cheetah (http://www.cheetahtemplate.org) verwenden. Ist eine absolut geniale Template Engine imho, ich verwende es in vielen Projekten. Du hast so eine sehr viel bessere Trennung von Inhalt und Programmlogik, ausserdem werden Cheetah Templates als Objekte gesehen, also funktioniert auch Vererbung und so.

Bis dahin

Sebastian
Leonidas
Python-Forum Veteran
Beiträge: 16025
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

Milan hat geschrieben:Danke übringens für das Modul PSP, hab gar nicht gewusst, dass es sowas gibt. Das muss ich mir mal näher anschauen, wenn ich Zeit habe.
Das ist afaik nur in mod_py 3 also nur für Apache 2.
My god, it's full of CARs! | Leonidasvoice vs (former) Modvoice
Antworten