Рамка бутылок и ООП, используя метод вместо функции
Я сделал некоторую кодировку с Бутылкой. Это действительно просто и соответствует моим потребностям. Тем не менее, я получил палку, когда попытался обернуть приложение в класс:
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?
Ответы
Ответ 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