【问题标题】:Looking to open pymongo database connection with decorator希望用装饰器打开 mongodb 数据库连接
【发布时间】:2021-09-15 08:52:15
【问题描述】:
@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 和文档传递回路由函数。

【问题讨论】:

    标签: python flask pymongo decorator python-decorators


    【解决方案1】:

    装饰器的工作原理基本上是用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') 获取参数“请求”。 (我不知道这是什么框架,所以我无法预测这个框架是否将请求作为函数参数提供)。

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

    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
    

    【讨论】:

    • 这真的很有帮助,感谢您的宝贵时间。这是烧瓶,它不会将请求作为参数传递。
    猜你喜欢
    • 2013-09-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多