Каркас бутылки и ООП, используя метод вместо функции - PullRequest
35 голосов
/ 04 января 2012

Я сделал немного кодирования с Bottle.Это действительно просто и соответствует моим потребностям.Тем не менее, я получил палку, когда попытался заключить приложение в класс:

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")

Можно ли использовать методы вместо функций в Bottle?

Ответы [ 5 ]

40 голосов
/ 04 января 2012

Ваш код не работает, потому что вы пытаетесь перенаправить на не связанные методы.Не связанные методы не имеют ссылки на self, как они могли бы, если экземпляр App не был создан?

Если вы хотите перенаправить методы класса, сначала вы должны инициализировать вашclass, а затем bottle.route() к методам этого объекта, например:

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)

Если вы хотите прикрепить определения маршрутов рядом с обработчиками, вы можете сделать что-то вроде этого:

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)

Не выполняйте часть bottle.route() в App.__init__(), потому что вы не сможете создать два экземпляра класса App.

Есливам больше нравится синтаксис декораторов, чем установка атрибута index.route=, вы можете написать простой декоратор:

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

class App(object):
    @methodroute('/index/')
    def index(self):
        pass
25 голосов
/ 18 декабря 2014

Вы должны расширить класс Bottle.Это примеры веб-приложений WSGI.

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)

То, что делает большинство примеров, включая ответы, ранее предоставленные на этот вопрос, - это повторное использование «приложения по умолчанию», не создание собственного и не использованиеудобство объектной ориентации и наследования.

25 голосов
/ 17 апреля 2013

Ниже хорошо работает для меня :) Достаточно объектно-ориентированный и простой в использовании.

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 голосов
/ 20 июля 2014

попробуй это, у меня получилось, документация тоже довольно приличная для начала ...

https://github.com/techchunks/bottleCBV
3 голосов
/ 14 января 2014

Я взял ответ @Skirmantas и немного изменил его, чтобы учесть аргументы ключевых слов в декораторе, такие как метод, пропуск и т. Д .:

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)
...