微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

希望用装饰器打开 pymongo 数据库连接

如何解决希望用装饰器打开 pymongo 数据库连接

@api.route('/api/get_contacts')
def get_contacts():
with pymongo.MongoClient(f"mongodb+srv://{mongo_username}:{mongo_password}@dev.glstt.mongodb.net/xxxx?retryWrites=true&w=majority") as document:

这个看的太多了。我正在努力使其成为:

@api.route('/api/get_contacts')
@mongo
def get_contacts():

问题是,我不太了解装饰器。 所以,这就是我到目前为止所做的:


def mongo(f):
    @wraps(f)
    def wrap (*args,**kwargs):
        with pymongo.MongoClient(f"mongodb+srv://{mongo_username}:{mongo_password}@dev.glstt.mongodb.net/xxx?retryWrites=true&w=majority") as document:

            return f(document)
        return wrap

不确定我需要做什么才能让装饰器在代码前面加上“with 运算符”,然后传递 x,然后将文档返回给路由函数

解决方法

装饰器的工作原理是用 decorator(function) 替换你的函数。例如:

@decorator
def my_function():
    pass

等于

def my_function():
    pass

my_function = decorator(my_function)

这意味着你可以从装饰器返回一个可调用的函数,每次你用参数调用它时,它都会用特定的参数调用被装饰的函数。

例如:

import functools

def decorator(decorated_function):
    @functools.wraps(decorated_function) # This means that the function that returns from this decorator,"wrapper",will keep the decorated_function's name,`__doc__` argument and more.
    def wrapper(*args,**kwargs):
        """
        Every time you will call the function that returned from the decorator,this function will be called with the particular arguments in args and kwargs.
        """
        return decorated_function(*args,**kwargs) + 10
    return wrapper


@decorator
def func(n):
    return n * 2

result = func(2) # here we called the function `wrapper`,the result is func(2) + 10,as we did when we called the function.

print(result) # 14

我们也可以print(func),结果类似于 <function func at 0x7f5eb16b0040>,如果我们没有使用 functools.wraps<function decorator.<locals>.wrapper at 0x7fba9ba0f040>

现在你的问题, 当你堆叠装饰器时,

@c
@b
@a
def func(): pass

订单是 c(b(a(func))) 因此,名为 mongo 的函数应该从 api.route('/api/get_contacts') 获取参数“request”。 (我不知道这是什么框架,所以我无法预测这个框架是否将请求作为函数参数提供)。

如果框架没有将请求作为参数传递:

def mongo(f):
    @functools.wraps(f)
    def wrap():
        with pymongo.MongoClient(f"mongodb+srv://{mongo_username}:{mongo_password}@dev.glstt.mongodb.net/xxx?retryWrites=true&w=majority") as document:
            return f(document)
    return wrap

如果有:

def mongo(f):
    @functools.wraps(f)
    def wrap(request):
        # do something with the request
        with pymongo.MongoClient(f"mongodb+srv://{mongo_username}:{mongo_password}@dev.glstt.mongodb.net/xxx?retryWrites=true&w=majority") as document:
            return f(document)
    return wrap

然后它允许你这样做:

@api.route('/api/get_contacts')
@mongo
def get_contacts(document):
    pass

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。