使用定义为实例变量的装饰器函数

时间:2016-12-22 05:12:24

标签: python flask decorator python-decorators

(虽然这个问题是关于Flask的,但可以根据标题推广)

我试图在课堂上使用Flask的app.route()装饰器。但是,Flask应用程序初始化为实例变量,即self.server设置为应用程序。这意味着我无法使用装饰器,因为self在装饰方法之外是未定义的。我希望能够做到以下几点:

class MyClass:

    def __init__(self):
        self.server = Flask(__name__)

    @self.server.route('/')
    def home():
        return '<h1>Success</h1>'

这个问题是否有解决方法?非常感谢任何帮助!

3 个答案:

答案 0 :(得分:3)

您应该使用route()对象的add_url_rule method,而不是使用self.server装饰器,如下所示:

class MyClass:
    def __init__(self):
        self.server = Flask(__name__)
        self.server.add_url_rule('/', 'home', self.home)
        self.server.add_url_rule('/route-1', 'route-1', self.route_1)
        self.server.add_url_rule('/route-2', 'route-2', self.route_2)

    def home():
        return '<h1>Success</h1>'

    def route_1():
        ...

    def route_2():
        ...

此模式允许您将路由处理程序定义为类中的方法,并且更容易阅读,因为您可以在一个块中查看所有URL规则。

答案 1 :(得分:2)

您可以在<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> <!DOCTYPE HTML> <html lang="en"> <head> <meta charset="utf-8"> <meta name="description" content="Contacts"> <title>Contacts</title> <link rel="stylesheet" type="text/css" href="style.css"> <script type="text/javascript" src="jquery.js"></script> <script type="text/javascript"> $(document).ready(function(){ $('button').click(function(){ var first = $('input.first').val(); var last = $('input.last').val(); var desc = $('textarea').val(); var p = $('<p class="card">'); p.append("<h1>"+ first +' '+last+"</h1><h4>'Click for description!'</h4><p class='back'>"+desc+"</p>"); $('div.right').append(p); return false; }); $(document).on('click', 'p.card', function(){ //this is the function I am trying to get to work. alert("test"); }); }); </script> </head> <body> <div class="wrapper"> <div class="left"> <form action="#"> <p >First name: <input type="text" name="fname" class="first"></p> <p >Last name: <input type="text" name="lname" class="last"></p> <p class="desc">Description:</p> <p><textarea rows="4" cols="50"></textarea></p> <button>Add User</button> </form> </div> <div class="right"> </div> </div> </body>方法的上下文中定义该函数。然后,要使函数能够正常调用,请将__init__成员设置为等于它。

home

答案 2 :(得分:2)

我不确定您的整体用例是什么,但是如果不将app对象嵌入到类中而是使用Flask的Pluggable Views模块,则可能会更好。这将允许您将视图干净地定义为从flask.views.View继承的类。例如:

import flask
import flask.views

class MyClass(flask.views.View):
  def dispatch_request(self):
    return '<h1>Success</h1>'

app.add_url_rule('/test', view_func=MyClass.as_view('home'))

对于小例子,这肯定是更多的代码,但是这使您可以更灵活地使用自己的路由定义其他类或函数,并且可能考虑使用MethodViews,它提供了一个用于定义多个HTTP方法并将它们关联的良好结构单班。