ubuntuusers.de

[Python] bottle @route

Status: Gelöst | Ubuntu-Version: Ubuntu 11.04 (Natty Narwhal)
Antworten |

Glocke

Avatar von Glocke

Anmeldungsdatum:
1. März 2009

Beiträge: 880

Wohnort: Thüringen

Hi, ich hab mal eine Frage zum @route einer Bottle() Instanz.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
from bottle import Bottle, run

def foo():
    return 'klappt'

app = Bottle()
@app.route('/')
def _foo():
    return foo()

run(app)
1
2
3
4
5
6
7
8
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

Avatar von 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)
Avatar von Glocke

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

Avatar von 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 Team-Icon

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

Avatar von 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)
Avatar von Glocke

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

Avatar von 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)
Avatar von Glocke

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

Avatar von 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

Avatar von 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 Team-Icon

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:

1
2
def my_func():
    return 'Hello World'

mybottle.py:

1
2
3
4
5
6
7
8
9
#!/usr/bin/python

from bottle import route, run, debug
import mylib

@route('/foo')
def foo():
    answer = mylib.my_func()
    return answer

Gruß, noisefloor

Lysander

Avatar von 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 Team-Icon

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)
Avatar von Glocke

Anmeldungsdatum:
1. März 2009

Beiträge: 880

Wohnort: Thüringen

Da ich momentan mein Gesamtkonzept überarbeite stell ich das Thema mal zurück ☺

Antworten |