2016-12-22 23 views
6

(Mặc dù câu hỏi này là cụ thể về Flask, nó có thể được khái quát hóa theo tiêu đề)Sử dụng một chức năng trang trí định nghĩa là một thể hiện biến

Tôi đang cố gắng sử dụng app.route() trang trí Flask của bên trong một lớp. Tuy nhiên, ứng dụng Flask được khởi tạo dưới dạng biến mẫu, tức là self.server được đặt thành ứng dụng. Điều này có nghĩa là tôi không thể sử dụng trang trí, vì self không được xác định bên ngoài phương thức được trang trí. Tôi muốn có thể thực hiện những việc sau:

class MyClass: 

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

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

Có bất kỳ xung đột nào cho vấn đề này không? Bất kỳ trợ giúp nào cũng được đánh giá rất cao!

Trả lời

2

Bạn có thể xác định hàm trong ngữ cảnh của phương thức __init__. Sau đó, để làm cho hàm có thể được gọi là bình thường, hãy đặt thành viên home bằng với nó.

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

     # This is indented at __init__'s level, so a new instance of the function 
     # is defined every time __init__ runs. That means a new instance 
     # is defined for each instance of the class, and so it can be wrapped with 
     # the instance's "self" value. 
     @self.server.route('/') 
     def home_func(): 
      return '<h1>Success</h1>' 

     # Then, you make it an object member manually: 
     self.home = home_func 
+0

Cảm ơn bạn! Điều đó hoạt động hoàn hảo –

+1

Tôi sẽ cho rằng đây không phải là giải pháp hướng tới tương lai, vì cuối cùng bạn sẽ có một phương thức '__init __()' chứa tất cả định nghĩa tuyến đường của bạn và chức năng tương ứng của chúng. Tốt hơn nên sử dụng hàm ['add_url_rule()' (http://flask.pocoo.org/docs/0.12/api/#flask.Flask.add_url_rule), như được giải thích trong câu trả lời của riêng tôi (và @rumdrums ') câu hỏi này. – YellowShark

+1

Trong trường hợp của Flask, đó có lẽ là tốt hơn. Tuy nhiên, đây là một câu hỏi tuyệt vời ngay cả đối với những người không sử dụng Flask. Ngoài ra, việc định nghĩa các hàm theo cách này chỉ mất thêm một dòng cho mỗi hàm so với 'add_url_rule', vì vậy tôi không nghĩ rằng" một phương thức '__init __()' lớn đặc biệt quan trọng. – IanPudney

2

Tôi không chắc chắn những gì trường hợp sử dụng tổng thể của bạn, nhưng bạn có thể được phục vụ tốt hơn bằng cách không nhúng các đối tượng ứng dụng trong một lớp học và thay vào đó sử dụng mô-đun Pluggable Views Flask của. Điều này sẽ cho phép bạn xác định rõ ràng lượt xem của mình dưới dạng các lớp kế thừa từ flask.views.View. Ví dụ:

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

Đây là mã chắc chắn hơn cho các ví dụ nhỏ, nhưng điều này giúp bạn linh hoạt hơn để xác định các lớp học hoặc các chức năng khác với các tuyến đường riêng của họ, và có khả năng để xem xét MethodViews thay vào đó, trong đó cung cấp một cấu trúc tốt cho việc xác định nhiều phương thức HTTP và liên kết chúng với một lớp duy nhất.

3

Thay vì sử dụng route() trang trí, bạn nên sử dụng add_url_rule method của đối tượng self.server, như vậy:

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

mô hình này cho phép bạn xác định xử lý tuyến đường của bạn như các phương pháp trên lớp và dễ dàng hơn nhiều để đọc, vì bạn có thể xem tất cả các quy tắc URL của mình trong một khối.

Các vấn đề liên quan