#python #flask #pymongo #decorator #python-decorators
Вопрос:
@api.route('/api/get_contacts')
def get_contacts():
with pymongo.MongoClient(f"mongodb srv://{mongo_username}:{mongo_password}@dev.glstt.mongodb.net/xxxx?retryWrites=trueamp;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=trueamp;w=majority") as document:
return f(document)
return wrap
Не уверен, что мне нужно сделать, чтобы декоратор добавил к коду «с оператором» и передал x, а затем документ обратно в функцию маршрута.
Ответ №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=trueamp;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=trueamp;w=majority") as document:
return f(document)
return wrap
И тогда это позволит вам сделать это:
@api.route('/api/get_contacts')
@mongo
def get_contacts(document):
pass
Комментарии:
1. Это действительно помогло, спасибо, что уделили мне время. Это колба, и она не передает запрос в качестве аргумента.