Подтвердить что ты не робот

Рамка бутылок и ООП, используя метод вместо функции

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

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?

4b9b3361

Ответ 1

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

Если вы хотите перейти к методам класса, сначала нужно инициализировать свой класс, а затем 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

Ответ 2

Вы должны расширить класс 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)

В большинстве примеров, включая ответы, ранее предоставленные этому вопросу, все они повторно используют "приложение по умолчанию", а не создают их собственные, а не используют удобство ориентации объектов и наследования.

Ответ 3

Ниже работает красиво для меня:) Весь предмет ориентирован и прост в использовании.

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

Ответ 4

Я взял @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)

Ответ 5

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

https://github.com/techchunks/bottleCBV