Glocke
Anmeldungsdatum: 1. März 2009
Beiträge: 880
Wohnort: Thüringen
|
Hi, ich hab mal eine Frage zum @route einer Bottle() Instanz. | from bottle import Bottle, run
def foo():
return 'klappt'
app = Bottle()
@app.route('/')
def _foo():
return foo()
run(app)
|
| from bottle import Bottle, run
def foo():
return 'klappt'
app = Bottle()
app.route(url='/', callback=foo)
run(app)
|
Das erste geht problemlos, beim zweiten erscheint 'not found:' im Browser. Ich wollte die umständliche Funktion _foo sparen (die zu callende foo möchte ich separat implementieren) Kann mir das jemand erklären? LG EDIT: Nachdem ich 3 Stunden erfolglos gesucht habe, habe ich eben die Lösung gefunden O_o 1
2
3
4
5
6
7
8
9
10
11
12
13 | import bottle
def foo():
return 'klappt'
def bar(text):
return text
app = bottle.app()
app.route('/')(foo)
app.route('/:text')(bar)
bottle.run(app)
|
Warum auch immer xDD LG
|
Lysander
Anmeldungsdatum: 30. Juli 2008
Beiträge: Zähle...
Wohnort: Hamburg
|
Auch wenn Du da augenscheinlich eine Lösung gefunden hast, so habe ich das eigentliche Problem gar nicht verstanden!
|
Glocke
(Themenstarter)
Anmeldungsdatum: 1. März 2009
Beiträge: 880
Wohnort: Thüringen
|
Lysander schrieb: Auch wenn Du da augenscheinlich eine Lösung gefunden hast, so habe ich das eigentliche Problem gar nicht verstanden!
die bindung der funktion an eine route ohne verwendung eines dekorators (und dazu notwendigen zusätzlichen funktion) lg
|
Lysander
Anmeldungsdatum: 30. Juli 2008
Beiträge: Zähle...
Wohnort: Hamburg
|
Glocke schrieb: Lysander schrieb:
die bindung der funktion an eine route ohne verwendung eines dekorators (und dazu notwendigen zusätzlichen funktion)
Das habe ich da schon rauslesen können. Aber wieso ist das so wichtig bzw. welches Problem willst Du damit lösen?
|
noisefloor
Anmeldungsdatum: 6. Juni 2006
Beiträge: 29567
|
Hallo, das würde mich jetzt auch mal interessieren, warum du den Dekorator nicht verwenden willst... ☺ Gruß, noisefloor
|
snafu1
Anmeldungsdatum: 5. September 2007
Beiträge: 2133
Wohnort: Gelsenkirchen
|
Glocke schrieb: EDIT: Nachdem ich 3 Stunden erfolglos gesucht habe, habe ich eben die Lösung gefunden O_o 1
2
3
4
5
6
7
8
9
10
11
12
13 | import bottle
def foo():
return 'klappt'
def bar(text):
return text
app = bottle.app()
app.route('/')(foo)
app.route('/:text')(bar)
bottle.run(app)
|
Warum auch immer xDD
Na, weil der Dekorator nunmal das Funktionsobjekt als Argument nimmt und auf diesem dann arbeitet. Die Implementierung von so etwas ist halt, dass man bewusst (hier: aus route() heraus) eine neue Funktion zurückgibt, die so tut, als sei sie die dekorierte Funktion. Tatsächlich leitet sie die i.d.R. meist beliebige Anzahl an möglichen Argumenten einfach an die eigentliche Funktion weiter (Forwarding / Wrapping). Das Anheften mittels @ an die zu wrappende Funktion ist ja nur eine andere (leichtere) Möglichkeit, genau das auszudrücken, was du letztlich selbst heraus gefunden hast. "Populär" ist das ja eigentlich erst geworden, als die neue @ -Syntax in Python eingebaut wurde. Daher wundert es mich ebenfalls, wieso du jetzt unbedingt sozusagen dagegen arbeiten willst. Hast du vielleicht Angst, dass mit deiner Funktion irgend etwas schlimmes passiert, wenn sie einen Dekorator erhält? Bottle tut in dem Moment nicht mehr als sie mit dem Routing-Mechanismus bekannt zu machen. Andernfalls würde die angeforderte URL nicht zur passenden Funktion "finden" (was sich wohl von selbst erklärt). Ansonsten passiert da nichts weiter. Du kannst die Funktion problemlos auch in einem anderen Kontext verwenden, sofern es deine Befürchtung war, dass dies nicht möglich wäre.
|
Glocke
(Themenstarter)
Anmeldungsdatum: 1. März 2009
Beiträge: 880
Wohnort: Thüringen
|
snafu1 schrieb: Na, weil der Dekorator nunmal das Funktionsobjekt als Argument nimmt und auf diesem dann arbeitet.
hätte ich mir auch denken können xD danke warum: naja ich verwende die routen auf instanz-methoden und will den routenkonstruktor nicht zwingend in der klassendefinition verwenden müssen lg
|
Lysander
Anmeldungsdatum: 30. Juli 2008
Beiträge: Zähle...
Wohnort: Hamburg
|
Glocke schrieb: warum: naja ich verwende die routen auf instanz-methoden und will den routenkonstruktor nicht zwingend in der klassendefinition verwenden müssen
Auch hier stellt sich mir die Frage: Warum nicht? Evtl. erklärst Du uns das mal an einem Beispiel? Ich habe den Verdacht, dass Du hier einen falschen Ansatz von Kapselung verfolgst - aber ohne mehr Details bleibt es bei dem Verdacht 😉
|
Glocke
(Themenstarter)
Anmeldungsdatum: 1. März 2009
Beiträge: 880
Wohnort: Thüringen
|
ganz einfach weil ich die klasse(n) unabhängig von bottle haben will. in meiner berufsschulzeit wurde uns angeraten, bibliotheken immer möglichst unabhängig von drittanbieter libs zu machen.
|
Lysander
Anmeldungsdatum: 30. Juli 2008
Beiträge: Zähle...
Wohnort: Hamburg
|
Glocke schrieb: ganz einfach weil ich die klasse(n) unabhängig von bottle haben will. in meiner berufsschulzeit wurde uns angeraten, bibliotheken immer möglichst unabhängig von drittanbieter libs zu machen.
Genau das habe ich mir gedacht. Damit verfolgst Du imho einen falschen Ansatz der Kapselung! Die Idee an sich ist ja richtig; du trennst Deine Logik von der Weboberfläche ab. Aber damit Du die Funktionalität im Zusammenspiel mit Bottle nutzen kannst, musst Du ja ein Modul schreiben, in dem Du ein "Mapping" von URL auf (Logik-)Funktion implementierst. Genau dafür bietet Bottle ja die Dekoratoren an! Insofern versuchst Du ein Problem zu lösen, welches bereits gelöst ist 😉
|
DasIch
Anmeldungsdatum: 2. November 2005
Beiträge: 1130
|
Glocke schrieb: ganz einfach weil ich die klasse(n) unabhängig von bottle haben will. in meiner berufsschulzeit wurde uns angeraten, bibliotheken immer möglichst unabhängig von drittanbieter libs zu machen.
Bottle ist allerdings keine Bibliothek sondern ein Rahmenwerk. Dementsprechend lässt sich diese Regel, die ohnehin etwas problematisch ist, nicht sinnvoll anwenden.
|
noisefloor
Anmeldungsdatum: 6. Juni 2006
Beiträge: 29567
|
Hallo, wenn du deine eigene Lib unabhängig machen willst, dann lade sie doch als Lib und rufe sie aus der Funktion mit Route dekoriert aus auf: Z.B.: mylib.py:
| def my_func():
return 'Hello World'
|
mybottle.py:
| #!/usr/bin/python
from bottle import route, run, debug
import mylib
@route('/foo')
def foo():
answer = mylib.my_func()
return answer
|
Gruß, noisefloor
|
Lysander
Anmeldungsdatum: 30. Juli 2008
Beiträge: Zähle...
Wohnort: Hamburg
|
@noisefloor: Genau das meinte ich - das Beispiel habe ich mir gespart, da ich dachte, dass der Schritt dann klar ist. IdR. wird man auch kaum den reinen Rückgabewert aus einer solchen Funktion zurückliefern, sondern den an ein Template übergeben o.ä.. Dies ist ja imho ein wesentlicher Aspekt bei der Verwendung eines Webrahmenwerks. Genau da sehe ich den ursprünglichen Denkfehler, das Routing per Dekorator vermeiden zu wollen.
|
noisefloor
Anmeldungsdatum: 6. Juni 2006
Beiträge: 29567
|
Hallo, yup, der "view" fehlt im meinem Minimalbeispiel. Natürlich ist volles MVC schöner. 😉 @Glocke: Wäre das eine Lösung für dich oder liegt dein Problem doch noch anders? Gruß, noisefloor
|
Glocke
(Themenstarter)
Anmeldungsdatum: 1. März 2009
Beiträge: 880
Wohnort: Thüringen
|
Da ich momentan mein Gesamtkonzept überarbeite stell ich das Thema mal zurück ☺
|