2012-01-04 11 views
32

yöntemini kullanarak Şişe ile bazı kodlama yaptım. Bu gerçekten basit ve ihtiyaçlarıma uyuyor. Bir sınıfa uygulamayı sarmak için çalıştım, ancak ben sopa var:Şişe çerçevesi ve OOP, işlev yerine

import bottle 
app = bottle 

class App(): 
    def __init__(self,param): 
     self.param = param 

    # Doesn't work 
    @app.route("/1") 
    def index1(self): 
     return("I'm 1 | self.param = %s" % self.param) 

    # Doesn't work 
    @app.route("/2") 
    def index2(self): 
     return("I'm 2") 

    # Works fine 
    @app.route("/3") 
    def index3(): 
     return("I'm 3") 

o Şişe yöntemleri yerine işlevlerini kullanmak mümkün mü?

+0

Neden bottleCBV https://github.com/techchunks/bottleCBV – Adeel

cevap

36

Kodunuz, bağlı olmayan yöntemlere yönlendirmeye çalıştığınız için çalışmaz. Bağlı olmayan yöntemler self referansına sahip değil, örneğin, App örneği oluşturulmamış olabilir mi?

sınıf yöntemlerine rota istiyorsanız, öncelikle sınıf başlatmak zorunda ve sonra bottle.route() şöyle bu nesne üzerinde yöntemlere: seni

import bottle   

class App(object): 
    def __init__(self,param): 
     self.param = param 

    def index1(self): 
     return("I'm 1 | self.param = %s" % self.param) 

myapp = App(param='some param') 
bottle.route("/1")(myapp.index1) 

İşleyici yakın rotalar tanımlarını sopa istiyorsanız Eğeriki örneğini oluşturmak mümkün olmayacaktır çünkü

def routeapp(obj): 
    for kw in dir(app): 
     attr = getattr(app, kw) 
     if hasattr(attr, 'route'): 
      bottle.route(attr.route)(attr) 

class App(object): 
    def __init__(self, config): 
     self.config = config 

    def index(self): 
     pass 
    index.route = '/index/' 

app = App({'config':1}) 
routeapp(app) 

App.__init__() yılında bottle.route() bölümünü yapmayın: böyle bir şey yapabilirizsınıfı. Daha özelliği index.route= ayarlamak yerine dekoratörler sözdizimini seviyorsanız

, basit bir dekoratör yazabilirsiniz:

def methodroute(route): 
    def decorator(f): 
     f.route = route 
     return f 
    return decorator 

class App(object): 
    @methodroute('/index/') 
    def index(self): 
     pass 
+0

Çok yardımcı oldu, Teşekkür ederim Skirmantas! –

+3

Not: bottle.route (attr.route, attr) 'amaçlandığı gibi çalışmayacaktır; bottle.route (attr.route) (attr) 'yi istediğinizden (çünkü bottle.route() bir dekoratördür, bu bir" callable "döndürür ve sonra" attr "()) kullanır. – larsks

+0

Not için teşekkürler! Onu düzeltti. – Ski

20

Aşağıda benim için güzel çalışıyor :) Oldukça nesne odaklı ve takip edilmesi kolay.

from bottle import Bottle, template 

class Server: 
    def __init__(self, host, port): 
     self._host = host 
     self._port = port 
     self._app = Bottle() 
     self._route() 

    def _route(self): 
     self._app.route('/', method="GET", callback=self._index) 
     self._app.route('/hello/<name>', callback=self._hello) 

    def start(self): 
     self._app.run(host=self._host, port=self._port) 

    def _index(self): 
     return 'Welcome' 

    def _hello(self, name="Guest"): 
     return template('Hello {{name}}, how are you?', name=name) 

server = Server(host='localhost', port=8090) 
server.start() 
3

Ben @Skirmantas cevabını aldı ve, vb yöntem gibi, dekoratör anahtar kelime argümanları izin atlamak için bunu biraz modifiye:

def routemethod(route, **kwargs): 
    def decorator(f): 
     f.route = route 
     for arg in kwargs: 
      setattr(f, arg, kwargs[arg]) 
     return f 
    return decorator 

def routeapp(obj): 
    for kw in dir(obj): 
     attr = getattr(obj, kw) 
     if hasattr(attr, "route"): 
      if hasattr(attr, "method"): 
       method = getattr(attr, "method") 
      else: 
       method = "GET" 
      if hasattr(attr, "callback"): 
       callback = getattr(attr, "callback") 
      else: 
       callback = None 
      if hasattr(attr, "name"): 
       name = getattr(attr, "name") 
      else: 
       name = None 
      if hasattr(attr, "apply"): 
       aply = getattr(attr, "apply") 
      else: 
       aply = None 
      if hasattr(attr, "skip"): 
       skip = getattr(attr, "skip") 
      else: 
       skip = None 

      bottle.route(attr.route, method, callback, name, aply, skip)(attr) 
2

bu deneyin, benim için çalıştı, dokümantasyon da oldukça iyi Sen Bottle sınıf genişletmek zorunda olan ...

https://github.com/techchunks/bottleCBV 
24

başlamak için. Örnekler WSGI web uygulamalarıdır.

from bottle import Bottle 

class MyApp(Bottle): 
    def __init__(self, name): 
     super(MyApp, self).__init__() 
     self.name = name 
     self.route('/', callback=self.index) 

    def index(self): 
     return "Hello, my name is " + self.name 

app = MyApp('OOBottle') 
app.run(host='localhost', port=8080) 

Çoğu örnekleri daha önce bu soruya verilen cevaplar dahil orada yapıyoruz dışında kendi yaratmak değil, ve nesne yönelimi ve miras kolaylık kullanmıyor, "Varsayılan uygulamayı" yeniden bütün.

+0

Eğer düzinelerce rota varsa? –

+0

@ Alex-Bogdanov, rotalarınızı bir şekilde tanımlamanız gerekiyor. Rotanızda joker karakterler olabilir, bu da bir yöntemi çağırmanıza ve kullandığınız rotaya göre bir parametre vermenize olanak tanır. Bu, gerçek olası rotaların daha az rota tanımlamasına sahip olmanızı sağlar. – jpcgt