15

我对 Python 有点陌生(我来自 Java/C++ 背景)。我一直在使用 Flask 进行 Web 开发。我的问题在某种程度上与依赖注入和线程安全有关。在 Java/Spring 单词中,您将拥有一个具有 Service 的 Controller,例如 UserService 注入其中。当你说一个 addUser 端点时,它会调用 userService.addUser(someData)。

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

4

1 回答 1

27

与所有与线程相关的事情一样,问题是“您是否使它成为线程安全的”?

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

# 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. ...
于 2013-05-21T14:48:46.143 回答