Seite 1 von 1

komischer Fehler

Verfasst: Montag 20. Oktober 2014, 09:26
von dodo
Hallo,

Ich baue zurzeit ein Templatesystem für mein eigenes Webframework.
Doch es funktioniert nicht wirklich...
Syntax: {%code%} code ist Python Code(z.B. print("Hallo")), {{code}} code ist auch Python code, allerdings wird hier die Rückgabe in den HTML-Code eingebaut. Mit \ kann man {{code}} als "{{code}}" ausgeben lassen(Das '{{' wird ignoriert) und mit \\ kann man einen Backslash ausgeben.

Das Problem ist: Bei "HTML{{python wert}}\\{{kein python code}}\\{%kein python code%}\\\\{%python code%}{%if irgendwas DO%}Irgendein HTML-Code{%END%}ende" kommt

Code: Alles auswählen

print("""HTML"""+python wert+"""{{kein python code}}{{kein python code%}""")
if irgendwas :
 print("""Irgendein HTML-Code""")

print("""ende""")
heraus.

So sieht der Code vom Template-System aus:

Code: Alles auswählen

class SETTemplate(object):
	def __init__(self, template):
		self.newTemplate(template)
	def newTemplate(self, template):
		self.template = "print(\"\"\""
		isPy = False
		isEv = False
		isStr = False
		isEsc = False
		tabs = 0
		index = 0
		while index < len(template):
			i = template[index]
			if isEsc:
				self.template+=i
				index+=1
				isEsc = False
			try:
				if i == "\\":
					isEsc = True
					index+=1
				elif i == "\"" and (isPy or isEv):
					self.template+="\""
					isStr = not isStr
					index+=1
				elif i == "{" and template[index+1] == "%" and not (isPy or isEv):
					self.template+="\"\"\")\n"+(" "*tabs)
					isPy = True
					index+=2
				elif i == "{" and template[index+1] == "{" and not (isPy or isEv):
					self.template+="\"\"\"+"
					isEv = True
					index+=2
				elif i == "%" and template[index+1] == "}" and isPy:
					isPy = False
					self.template+="\n"+(" "*tabs)+"print(\"\"\""
					index+=2
				elif i == "}" and template[index+1] == "}" and isEv:
					isEv = False
					self.template+="+\"\"\""
					index+=2
				elif i == "D" and template[index+1] == "O" and isPy:
					self.template+=":"
					tabs+=1
					index+=2
				elif i == "E" and template[index+1] == "N" and template[index+2] == "D" and isPy:
					tabs-=1
					if tabs<0:
						tabs = 0
					index+=3
				else:
					self.template+=i
					index+=1
			except:
				try:
					self.template+=i
					index+=1
				except:
					break
		self.template+="\"\"\")"
		return self.template
Hilfe wäre nett
Danke im Vorraus,

Dodo

Re: komischer Fehler

Verfasst: Montag 20. Oktober 2014, 09:46
von BlackJack
@dodo: Nimm `jinja2`. Oder etwas anderes fertiges.

Ansonsten solltest Du die ”Fehlerbehandlung” überarbeiten. Diese vielen nackten ``except``\s sind keine gute Idee. Ebenso ist das zeichenweise verarbeiten des Templates und erzeugen des Codes keine besonders gute Idee. Das ist hochgradig ineffizient, das zeichenweise verarbeiten weils in Python passiert und das erzeugen des Codes weil Zeichenketten unveränderbar sind, also für fast jedes Zeichen alles bisherige einmal im Speicher herumkopiert werden muss, nur um ein weiteres Zeichen oder eine kurze Zeichenkette anzufügen. Mühsam zu lesen ist dieser Zustandsautomat auch.

Ich würde zuerst einmal das Template mit regulären Ausdrücken in Token zerlegen.

Re: komischer Fehler

Verfasst: Montag 20. Oktober 2014, 09:59
von Sirius3
@dodo: zusätzlich zu dem, was BlackJack schon geschrieben hat: Konvention für die Einrücktiefe ist vier Leerzeichen pro Ebene. Ein Blick in den Style Guide for Python Code könnte sich lohnen.
'i' ist ein äußerst schlechter Name für ein Zeichen, da ich (und viele andere) bei 'i' an eine Zahl, insbesondere an einen Laufindex einer Schleife, denken. Python kennt auch das einfache Anführungszeichen als Stringmarkierung. Damit lassen sich die vielen \" vermeiden und die Strings werden deutlich lesbarer. Der Template-Funktionsgenerator sollte statt einer Funktion mit "print" eine mit Stringverarbeitung erzeugen. Solche Funktionen lassen sich viel flexibler einsetzen. Da jeweils nur eines von isPy, isEv, isStr oder isEsc True sein kann, ließe sich diese Variablen zu einer Zustandsvariable zusammenfassen.

Re: komischer Fehler

Verfasst: Montag 20. Oktober 2014, 12:40
von snafu
@dodo: Neben dem, was die Vorposter geschrieben haben, ist es außerdem unsinnig, eine Klasse zu erstellen, die im Grunde nur aus einer einzigen Methode besteht. Das kann man auch gleich als Funktion schreiben. Klassen werden (unter anderem) dann sinnvoll, wenn du die Arbeit in verschiedene Funktionen gliederst und merkst, dass du gemeinsame Parameter benutzt. Dann kann man diese gemeinsamen Parameter nämlich als Instanzattribute seiner Klasse definieren. Diesen Umstand sehe ich beim bisherigen Zustand deines Programms aber nicht.