Python / Flask服务层的最佳实践

时间:2013-05-20 15:55:35

标签: python flask

我对Python有点新手(我来自Java / C ++背景)。我一直在玩Flask进行网页开发。我的问题在某种程度上与依赖注射和线程安全有关。在Java / Spring中,你会有一个控制器,它有一个服务说UserService注入其中。当你说一个addUser端点时,它会调用userService.addUser(someData)。

如果我想在Python / Flask中做同样的事情,最好的做法就是使用addUser(),deleteUser()等函数来创建一个名为UserService的文件,然后用UserService.addUser(),UserService直接调用它们。 deleteUser()并且这个线程安全吗?或者我应该在每个端点都有一个新的用户服务实例吗?

1 个答案:

答案 0 :(得分:14)

与线程相关的所有内容一样,问题是“你是否使其成为线程安全的”?

如果您的用户服务如下所示:

# user_service.py
from some.package import database

def add_user(user_information=None):
    db = database.connect()
    db.insert(user_information)

def update_user(user_information=None):
    db = database.connect()
    db.update(user_information["user_id"], user_information)

def delete_user(user_id=None):
    db = database.connect()
    db.delete(user_id)

然后,假设some.package.database甚至是远程理解的实现,它将是线程安全的。另一方面,如果你做这样的事情:

# bad_user_service.py
from some.package import database

# Shared single connection
# Probably *not* thread safe
db = database.connect()

def add_user(user_information=None):
    db.insert(user_information)

# ... etc. ...

现在,在每个服务方法的顶部都包含db = database.connect()非常不干。您可以通过在装饰器中包装特定于连接的工作来避免该问题(例如):

def provide_db(func):

    @functools.wraps(func)
    def new_function(*args, **kwargs):
        db = database.connect()
        return func(db, *args, **kwargs)

    return new_function

然后你可以这样做:

# user_service.py
from your.data.layer import provide_db

@provide_db
def add_user(db, user_information=None):
    db.insert(user_information)

# ... etc. ...