Я написал функцию декоратора для системы пользовательских разрешений Flask. Когда я пытаюсь поразить вид, украшенный им, я получаю UnboundLocalError
по параметру user
. Вот функция декоратор:Несогласованный объем параметров в декораторе
def user_is(role, user=None):
"""
Takes an role (a string name of either a role or an ability) and returns the function if the user has that role
"""
def wrapper(func):
@wraps(func)
def inner(*args, **kwargs):
from .models import Role
desired_role = Role.query.filter_by(
name=role).first()
if not user:
try:
from flast.ext.login import current_user as user
except ImportError:
raise ImportError(
'User argument not passed and Flask-Login current_user could not be imported.')
if desired_role in user.roles:
return func(*args, **kwargs)
else:
# Make this do someting way better.
return "You do not have access"
return inner
return wrapper
отслеживающий указывает user
неопределен для if not user:
. Я не уверен, как это может быть. Я понимаю, что если user
не существует в области внутренней функции, Python будет выходить за уровень по вложенным функциям до тех пор, пока не найдет его. Это означает, что я должен получить только UnboundLocalError
, если user
не определено в функции, все функции завершают ее и глобально. Это явно не так.
Другим источником путаницы является то, что я могу видеть с помощью консоли отладки Werkzeug, что мой другой параметр - это, определенный в этой области. Как определить один параметр, а другой параметр, который принимает функция декоратора, не определен в той же точке в потоке программы? Я подумал, что это была причуда, которая затрагивала только параметры со значением по умолчанию, поэтому я переключил ее на требуемый параметр и вручную передал в None
, но это все еще вызывало ошибку?
Почему user
не входит в сферу применения, когда другой параметр находится в области? Как я могу исправить этот декоратор?
Это имеет смысл. Один последующий вопрос, который поможет мне понять: как импорт влияет на область «пользователь», когда исключение возникает до того, как выполняется импорт? – raddevon
Компилятор перечисляет все назначения в функции; все, что присваивается (включая импорт), помечено как локальное, автоматически. Все остальное является свободной переменной. Если у родительской области есть соответствующие локальные, свободные переменные будут смотреться с закрытий, иначе они являются глобальными. Вы можете использовать ключевое слово 'global', чтобы переопределить это (пометьте локальный как глобальный), Python 3 также добавляет ключевое слово' nonlocal'. * Где * происходит импорт или назначение, не имеет значения. Любая ссылка на имя перед присвоением или импортом вызывает исключение 'UnboundLocal'. –