Losing variable scope inside a Python decorator -
this simple decorator works expected:
def protect(*permissions): def outer(f): def inner(*args): print permissions[0] return f(*args) return inner return outer @protect('protected') def func(var): return var print func('something')
the output is:
protected
moving beyond python shell , using decorator in larger scope of project, strange happening: while inside of inner
function, permissions
not defined.
i'm thinking there must python variable scoping/decorator subtleties i'm unaware of causing this. insights appreciated.
in mind figure out going on - let me try spell out:
it has python not "perceiving" "permissions" variable existing on scopes outside "inner" function - since when "inner" defined, "permissions" long have been defined in 'outsidemost' scope of protect. thus, when compiling inner
variale taken being global variable. (that why exact error message needed - nameerrors can local variables used before definition, or non-existing global variables - exact message tell in case)
in other words, likley have hit implementation bug - please try expose minimum ammount of code causes issue , exact python version using. if possible try latest micro version available - , ten time open issue @ bugs.python.org
i see 2 workarounds -- first 1 hack confirm diagnosis - , might not work @ all: make reading access permissions
variable on outer
function, outside inner
's body: should make interpretor "perceive" non-local variable in outer, , propagate inner.
the other workaround more solid , consistent - , maybe better code-styling yu in case: use class decorator in case, instead of relying on multiple nested functions , closures.
the above snippet rewritten as:
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')
this code not rely on nested closures, avoidnign bug you've hit. besides, follows "flat better nested" , "explict better implicit" coding guidelines.
but please, trace bug, giving version , code triggers behavior, if not opening issue @ python.org
Comments
Post a Comment