Frage zu ''exec''

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
EnTeQuAk
User
Beiträge: 986
Registriert: Freitag 21. Juli 2006, 15:03
Wohnort: Berlin
Kontaktdaten:

Hallo!

Ich bastel grad an einer Art Template Engine (Is aber wirklich nur indirekt eine :) ). Bei dieser soll in einem Template Code ausgeführt werden können.

Nun habe ich mir mal ein paar Template-Engines angeschaut, wie die das machen. Die meißten (oder alle...) machen das mit ''exec''. Jedoch lese ich oft etwas, das das sehr unsicher ist.
Nun habe ich mir überlegt. Einige bieten nicht die direkte Codeausführung sondern wie Jinja z.B. nur einzelne ''if'' oder ''while'' Befehle an (so weit wie ich das gesehen habe). Wie ist so etwas am besten und leichtesten umzusetzen.

Ich benötige hier keine Lösung oder so etwas sondern wirklich nur einen kleinen Hinweis/Anfang, wie man da rangehen kann.

Vielen Dank!

MfG EnTeQuAk
Benutzeravatar
jens
Python-Forum Veteran
Beiträge: 8502
Registriert: Dienstag 10. August 2004, 09:40
Wohnort: duisburg
Kontaktdaten:

Wes wegen es unsicher ist, kannst du dir sicherlich denken ;)

Generell sollte IMHO so wenig Logik in einem Template als unbedingt nötig. Deswegen kommt man auch mit sehr einfachen IF aus... Von daher kann man so Ausdrücke auch leicht parsen und verarbeiten...

Aber warum eigentlich eine neue Template Engine bauen, wenn es so schöne wie jinja gibt??? Was soll deine besser/anders können?

GitHub | Open HUB | Xing | Linked in
Bitcoins to: 1JEgSQepxGjdprNedC9tXQWLpS424AL8cd
EnTeQuAk
User
Beiträge: 986
Registriert: Freitag 21. Juli 2006, 15:03
Wohnort: Berlin
Kontaktdaten:

jens hat geschrieben:Wes wegen es unsicher ist, kannst du dir sicherlich denken ;)
Jo direkt... :) Schon :D
jens hat geschrieben:Generell sollte IMHO so wenig Logik in einem Template als unbedingt nötig. Deswegen kommt man auch mit sehr einfachen IF aus... Von daher kann man so Ausdrücke auch leicht parsen und verarbeiten...
Wer hat von einem normalen Template für eine Internetseite z.B. geredet?

jens hat geschrieben:Aber warum eigentlich eine neue Template Engine bauen, wenn es so schöne wie jinja gibt??? Was soll deine besser/anders können?
Wer hat von einer Template-Engine geredet? Es soll eine ART Template-Engine werden. Nur mit sehr wenigen Funktionen. Aber eine soll das direkte Ausführen von Code aus Templates werden.
Diese TEmplates sind direkt auch keine Templates mit HTML oder so :) Das is etwas anders... etwas eigenes ;)

Mir gings halt nur um nen Anhaltspunkt. Ne WHILE-Schleife bräuchte ich warscheinlich doch schon.

Ich schaue mir mitlerweile schon den Jinja-Code am um etwas zu erfahren. Aber so ganz seh ich net durch bzw. ich muss mich erstmal reinlesen :)


MfG EnTeQuAk
Benutzeravatar
jens
Python-Forum Veteran
Beiträge: 8502
Registriert: Dienstag 10. August 2004, 09:40
Wohnort: duisburg
Kontaktdaten:

Was sind denn genau die Anforderung / Aufgabe deiner Template Engine???

btw. jinja kann alles produzieren, ist also nicht auf HTML, XML oder sonstwas beschränkt...

GitHub | Open HUB | Xing | Linked in
Bitcoins to: 1JEgSQepxGjdprNedC9tXQWLpS424AL8cd
EnTeQuAk
User
Beiträge: 986
Registriert: Freitag 21. Juli 2006, 15:03
Wohnort: Berlin
Kontaktdaten:

IF - WHILE Blöcke ausführen. Direkten Code ausführbar machen.

Variablen ausführen. Hier z.B. VERSCHIEDENE Syntaxen erlauben, die Dynamisch zugewiesen werden. (lässt dem Programierer auf der anderen Seite mehr Freiheiten). Konfigurierbar via Configurationsdatei. Daten werden Dynamisch eingefügt. Können während des Ausführens geändert werden.

Aber das alles ist sekundär... Ich will damit auch etwas selbst üben. Ich will das Blatt auch net neu erfinden... nur so.

Ich wollte einfach nur ein paar Informationen, Beispiele haben. Mehr net :(


MfG EnTeQuAk
EnTeQuAk
User
Beiträge: 986
Registriert: Freitag 21. Juli 2006, 15:03
Wohnort: Berlin
Kontaktdaten:

Ich komm nicht so wirklich weiter...

Wie ich direkt Code ausführen kann hab ich nun hinbekommen. Einfach die Stellen direkt beim Rendern ausführen.

Aber Blöcke wie WHILE und IF - Abfragen raff ich net.

Hab übrigens endlich mal die '' config.py '' bei Jinja gefunden :D

Trotzdem ich lass mich net davon abbringen zu lernen ;)


Jmd. ein paar Vorschläge, Ideen?

Will ja nur nen Anschubs bekommen, --> Bei Jinja usw. müsste ich mich erst durcharbeiten. Dazu fehlt mir leider die Zeit.

MfG EnTeQuAk


EDIT: wie macht Jinja das? Entweder bin ich blind oder ich find die stellen net *heul* ...
sape
User
Beiträge: 1157
Registriert: Sonntag 3. September 2006, 12:52

Ich hoffe ich hab dich richtig verstanden:

Code: Alles auswählen

scr = """
foo = "bar"
if foo == "bar": print "blubb"; print "^^";
"""
exec(scr)
output:

Code: Alles auswählen

blubb
^^
Da man die in einem tpl schlecht den Code syntaktisch einrücken kann(?), trennst du einfach mit ";". Aber ob das die Beste Lösung ist :?

lg
EnTeQuAk
User
Beiträge: 986
Registriert: Freitag 21. Juli 2006, 15:03
Wohnort: Berlin
Kontaktdaten:

Mir ging es mehr um so stellen wie:

dumm zusammengestellter Bsp. Code, der so net funktionieren muss

Code: Alles auswählen

template = file(template_path+template+template_suffix)
code = 'ha'
return template.renderTemplate(template, vars)  
# Vars wurde vorher schon definiert
# rueckgabe immo als String. soll mit Colubrids HttpRequest() gemacht werden
code, ausm Template, der später funktionieren soll

Code: Alles auswählen

[IF: code == 'ha': print 'Ha ist gegeben']
Oder halt ne komplett andere Syntax...

Code: Alles auswählen

[IF: code == 'ha']
<p>Das hier wird dann ausgegeben ;)</p>
Hier überlege ich, ob ein [ENDIF] nötig sein wird...
So könnte man evtl. über einen Parser ein Temporäres Template erstellen, mit Syntaktischer Einrückung... hätte das Sinn?

Nur hab ich so richtig kein Plan, wie ich so etwas realisieren könnte. Möchte es aber gerne mal selber machen... ;) Hier und da ein paar Ideen aber so richtig nichts gutes....

MfG EnTeQuAk

PS: das sind nur ein paar Dumme Beispiele hier... bitte nicht direkt beachten ;)
mitsuhiko
User
Beiträge: 1790
Registriert: Donnerstag 28. Oktober 2004, 16:33
Wohnort: Graz, Steiermark - Österreich
Kontaktdaten:

EnTeQuAk hat geschrieben:Hab übrigens endlich mal die '' config.py '' bei Jinja gefunden :D
Die keine Config Datei ist
EDIT: wie macht Jinja das? Entweder bin ich blind oder ich find die stellen net *heul* ...
Jinja ist im Vergleich zu anderen Template Engines unglaublich kompliziert weil es nicht Python Code erzeugt, sondern Verschachtelte Knoten deren render Funktion rekursiv aufgerufen wird. Für eine Mini Template Engine schau dir stpy an.
TUFKAB – the user formerly known as blackbird
EnTeQuAk
User
Beiträge: 986
Registriert: Freitag 21. Juli 2006, 15:03
Wohnort: Berlin
Kontaktdaten:

blackbird hat geschrieben:
EnTeQuAk hat geschrieben:Hab übrigens endlich mal die '' config.py '' bei Jinja gefunden :D
Die keine Config Datei ist
Hab sie auch noch net ausprobiert... aber kann man da nicht das "Design" von Variablen bestimmen? Oder ist die nur so zum Spaß da?
blackbird hat geschrieben:
EDIT: wie macht Jinja das? Entweder bin ich blind oder ich find die stellen net *heul* ...
Jinja ist im Vergleich zu anderen Template Engines unglaublich kompliziert weil es nicht Python Code erzeugt, sondern Verschachtelte Knoten deren render Funktion rekursiv aufgerufen wird. Für eine Mini Template Engine schau dir stpy an.
stpy hab ich mir auch schon angesehen. Aber das ist halt zusammengeschrumpfter Code... ;) ich muss mich da erstmal durcharbeiten... :D

Hab mir Jinja noch nicht weiter angeschaut aber das es so Kompliziert ist... :D. Aber was sind
Verschachtelte Knoten deren render Funktion rekursiv aufgerufen wird
?? Kannst du das etwaserläutern?
Darunter kann ich mir überhaupt nichts vorstellen.


MfG EnTeQuAk
mitsuhiko
User
Beiträge: 1790
Registriert: Donnerstag 28. Oktober 2004, 16:33
Wohnort: Graz, Steiermark - Österreich
Kontaktdaten:

EnTeQuAk hat geschrieben:?? Kannst du das etwaserläutern?
Darunter kann ich mir überhaupt nichts vorstellen.
Folgendes Template:

Code: Alles auswählen

{% for item in seq %}
  {{ item }}
{% endfor %}
Wird vom Lexer in mehrere Teile geteilt. In diesem Fall etwa diese hier:

Code: Alles auswählen

[Token(''),
 Token('{% for tiem in seq %}'),
 Token('\n  {{ item }}\n')
 Token('{% endfor %}]
Der Parser unterscheidet dann zwischen Text Tokens und Block Tokens (letztere sind {% foo %} und {{ foo }}). Über einen zwischengeschalteten Token Parser werden diese gegen Parserregeln, die in der übergeben Parser Bibliothek definiert sind überprüft. In diesem Fall würde das in einen ForLoopTag und ein Paar einfache TextNodes. Solche Nodes (Knoten) können Referenzen auf andere Knoten speichern. Der ForLoopTag zb hat eine liste aus Knoten die in ihm defininiert sind. Das Template ruft dann von der globalen Nodelist die render() methode auf, die rekursiv alle darin liegenden Nodes mitrendert.
TUFKAB – the user formerly known as blackbird
EnTeQuAk
User
Beiträge: 986
Registriert: Freitag 21. Juli 2006, 15:03
Wohnort: Berlin
Kontaktdaten:

Okeeee.... kappiert. Aber musste das wirklich so kompliziert sein??? :D

Na Ja ;) So weit ganz gut. Aber ein paar sehr gute IDeen sind da mit drinne. Die werde ich mal versuchen etwas zu vereinfachen... Mal schauen, was am Ende bei rauskommt.

Danke für die schönen Tipps!


MFG EnTEQuAk
sape
User
Beiträge: 1157
Registriert: Sonntag 3. September 2006, 12:52

EnTeQuAk hat geschrieben:Okeeee.... kappiert.
Freut mich da du mir das dann erklären kannst. :D Ich hab ehrlich _nichts_ von dem verstanden (oder kaum) was Bird geschrieben hat xD
EnTeQuAk hat geschrieben: Aber musste das wirklich so kompliziert sein??? :D
Gute Frage ^^

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

EnTeQuAk hat geschrieben:Aber musste das wirklich so kompliziert sein??? :D
Das ist bei näherem betrachten gar nicht mal so kompliziert, es ist dafür sehr mächtig und flexibel. Und wer denkt, dass Content parsen einfach ist, sei eines besseren belehrt. Der Ansatz über Tokens ist sehr sauber und erweiterbar, was zum beipeil bei simplen Regex-Parsern eher nicht der Fall ist. Aber man nutzt Regex-Parser auch nur für weniger komplizierte Sachen.

Weitere Infos zu Themen wie dem Abstract Syntax Tree bietet die Wikipedia.
My god, it's full of CARs! | Leonidasvoice vs (former) Modvoice
EnTeQuAk
User
Beiträge: 986
Registriert: Freitag 21. Juli 2006, 15:03
Wohnort: Berlin
Kontaktdaten:

Und wer denkt, dass Content parsen einfach ist, sei eines besseren belehrt.
Jupp ;) Bemerke ich grad... Aber so langsam hab ich den Dreh raus, wie es klappen könnte... aber wirklich. Das ist heftig, auf was man alles achten muss, wenn es gut werden soll :D


MfG EnTeQuAk
sape
User
Beiträge: 1157
Registriert: Sonntag 3. September 2006, 12:52

Und wie realisert man (in verständlichen worten ;)) ein AST? Gibt es darüber gute Literatur die man auch versteht wenn man nicht gerade Studiert hat und was nicht zu Akademisch in den Formulierungen klingt?

lg
BlackJack

Also eines der Standardwerke in dem Bereich ist das "Dragon Book", so benannt wegen des Bildes auf dem Umschlag, von dem dieses Jahr gerade eine aktualisierte Auflage herausgekommen ist. Korrekter Titel ist "Compilers -- Principles, Techniques, and Tools" von Aho, Alfred V. / Lam, Monica S. / Ullman, Jeffrey D.

Ist zwar Fachliteratur, aber bei englischer Fachliteratur legen die Autoren meistens Wert auf Verständlichkeit. Bei deutschen Autoren habe ich manchmal das Gefühl die wollen damit angeben, dass sie etwas möglichst knapp, formal und schwerverständlich formulieren können. :-)

Das Buch ist aber sehr umfangreich und nicht gerade billig. Lohnt sich wahrscheinlich nicht wenn man nicht wirklich einen Compiler schreiben möchte oder Informatik studiert.

Grundsätzlich bekommt man einen AST aus einem Stück Quelltext indem man es "parst". Dazu braucht man eine Grammatik, welche die Sprache beschreibt und einen Parser der diese Grammatik erkennt. Der kann dann aus einem Quelltext einen AST aufbauen.

Das Thema ist dann aber ein bisschen zu komplex um es mal eben hier zu erklären würde ich sagen. Einfacher wird es, wenn man einen Parser-Generator benutzt, dem man eine Grammatik gibt und der entsprechenden Code generiert um Quelltext nach dieser Grammatik zu parsen. Bei Python finde ich `PyParsing` am nettesten, da baut man die Grammatik aus Objekten zusammen. `yapps2` erzeugt für Menschen "lesbaren" Quelltext, erkennt aber nur eine bestimmte Klasse von Sprachen. Für C hat mir `lemon` bisher am besten gefallen.
sape
User
Beiträge: 1157
Registriert: Sonntag 3. September 2006, 12:52

Oh, ok. Englisch ist nicht so mein Ding ;)
Ein Deutsches Buch sollte es schon sein, das aber halt nicht so kompliziert Formuliert ist und halt auch ein normaler Mensch verstehen kann, ohne Professor zu sein :) Ich sehe das auch so das viele Deutsch bücher so Klingen so wie du es meintest.

Aber mal ne Frage Jack: Das hier wäre ein sehr schlechter Ansatz oder?:

http://paste.pocoo.org/show/306/

Sorry, der Code ist ncoh __sehr__ Suboptimal und vieles könnte man auch ohne diese vielen Verzweigungen schon vorher behandeln. Ist eben sehr """schnell""" geschrieben von mir (hab ca. 1,5-2 Stunden gestern daran gesessen. EDIT: Wusste seit gestern noch nicht wie man regExe mit Python _richtig_ benutzt. Nun weiß ichs :)). Auch denke ich das hierfür regExe wohl nicht so sinnvoll ist und man lieber mit Stacks arbeiten sollte? -> http://www.rg16.asn-wien.ac.at/~python/ ... /kap18.htm

Aber mit AST verstehe ich noch nicht ganz worum es geht. Soll man aus die Tokens auf Objekte abbilden (so ne art Verzweigung von Objekten)? Ist doch nicht sinnvoll oder? Dann doch lieber alles parsen und dann den Code erzeugen der dann ausgeführt wird :?

lg
BlackJack

XtraNine hat geschrieben:Aber mal ne Frage Jack: Das hier wäre ein sehr schlechter Ansatz oder?:

http://paste.pocoo.org/show/306/
Naja, wie Du selbst geschrieben hast, sind die regulären Ausdrücke hier ein bisschen übertrieben. Das bekäme man mit `str.split()` und anderen Methoden auf Zeichenketten auch hin.
Auch denke ich das hierfür regExe wohl nicht so sinnvoll ist und man lieber mit Stacks arbeiten sollte? -> http://www.rg16.asn-wien.ac.at/~python/ ... /kap18.htm

Aber mit AST verstehe ich noch nicht ganz worum es geht. Soll man aus die Tokens auf Objekte abbilden (so ne art Verzweigung von Objekten)? Ist doch nicht sinnvoll oder?
Bei dem Beispiel auf der Webseite mit dem Stack braucht man natürlich keinen AST, die Postfix-Notation hat ja gerade die nette Eigenschaft, dass man das mit dem Stack einfach von links nach rechts auswerten kann. So einfach sind die meisten Sprachen leider nicht.
Dann doch lieber alles parsen und dann den Code erzeugen der dann ausgeführt wird :?
Das Ergebnis vom parsen ist in den meisten Fällen ein AST, aus dem dann der Zielcode erzeugt wird. Oder wie in dem Beispiel von blackbird gibt's auf den Knoten im AST Methoden die das Programm ausführen. Soweit ich weiss wird bei Ruby auch der AST "ausgeführt". CPython erzeugt aus dem AST nach dem parsen Bytecode für eine virtuelle Maschine.
Antworten