По моему мнению, я могу понять, что происходит - позвольте мне попытаться объяснить это:
это связано с тем, что Python не «воспринимает» переменную «permissions», как существующую в областях видимости вне«внутренняя» функция - поскольку, когда «внутреннее» само определено, «разрешения» долго бы определялись в «самой внешней» области защиты.Таким образом, при компиляции inner
переменная считается глобальной переменной.(Вот почему необходимо сообщение об ошибке точный - NameErrors может быть для локальных переменных, используемых до определения, или для несуществующих глобальных переменных - точное сообщение в этом случае многое скажет)
* 1007Другими словами, вы, скорее всего, столкнулись с ошибкой реализации - пожалуйста, попробуйте указать минимальное количество кода, вызывающего проблему, и точную версию Python, которую вы используете.Если возможно, попробуйте использовать последнюю доступную микро-версию - и десять будет пора открыть проблему на bugs.python.org
Я вижу два обходных пути - первый будет хаком, который подтвердитмой диагноз - и может вообще не сработать: создать доступ для чтения к переменной permissions
в функции outer
вне тела inner
: это должно заставить интерпретатора "воспринимать" ее как нелокальную переменнуюво внешнем, и распространите его во внутреннее.
Другой обходной путь является более надежным и непротиворечивым - и, возможно, в этом случае может даже улучшить стилизацию кода для yu: в этом случае использовать класс в качестве декоратора вместополагаясь на несколько вложенных функций и их замыканий.
Приведенный выше фрагмент может быть переписан как:
class Protect(object):
def __init__(self, *permissions):
self.permissions = permissions
def __call__(self, f):
def inner(*args):
print self.permissions[0]
return f(*args)
return inner
@Protect('protected')
def func(var):
return var
print func('something')
Этот код не основан на вложенных замыканиях, поэтому следует избегать ошибок, с которыми вы столкнулись.Кроме того, из этого следует, что «плоский лучше, чем вложенный» и «явный лучше, чем неявный» рекомендации по кодированию.
Но, пожалуйста, помогите всем отследить эту ошибку, предоставив нам свою версию и код, который фактически вызывает этоповедение, если не открывается проблема на python.org