Tengo un fragmento de código siguiente:problema local variable en Python
def isolation_level(level):
def decorator(fn):
def recur(level, *args, **kwargs):
if connection.inside_block:
if connection.isolation_level < level:
raise IsolationLevelError(connection)
else:
fn(*args, **kwargs)
else:
connection.enter_block()
try:
connection.set_isolation_level(level)
fn(*args, **kwargs)
connection.commit()
except IsolationLevelError, e:
connection.rollback()
recur(e.level, *args, **kwargs)
finally:
connection.leave_block()
def newfn(*args, **kwargs):
if level is None: # <<<< ERROR MESSAGE HERE, Unbound local variable `level`
if len(args):
if hasattr(args[0], 'isolation_level'):
level = args[0].isolation_level
elif kwargs.has_key('self'):
if hasattr(kwargs['self'], 'isolation_level'):
level = kwargs.pop('self', 1)
if connection.is_dirty():
connection.commit()
recur(level, *args, **kwargs)
return newfn
return decorator
Realmente no importa lo que hace, sin embargo, que lo ponga en su forma original, ya que era incapaz de recrear la situación con algo más simple.
El problema es que cuando llamo a isolation_level(1)(some_func)(some, args, here)
obtengo la excepción Unbound local variable
en la línea 21 (marcada en el listado). No entiendo por qué. Traté de volver a crear la misma estructura de funciones y llamadas a funciones que no contuviera todos los detalles de implementación para descubrir qué es lo que está mal. Sin embargo, no recibo el mensaje de excepción. Por ejemplo, las siguientes obras:
def outer(x=None):
def outer2(y):
def inner(x, *args, **kwargs):
print x
print y
print args
print kwargs
def inner2(*args, **kwargs):
if x is None:
print "I'm confused"
inner(x, *args, **kwargs)
return inner2
return outer2
outer(1)(2)(3, z=4)
Prints:
1
2
(3,)
{'z': 4}
¿Qué me falta ??
EDITAR
Ok, por lo que el problema es que en la primera versión que se realizan realmente una asignación a la variable. Python detecta eso y, por lo tanto, asume que la variable es local.
El mensaje de error se puede reproducir en unas pocas líneas, y es fácil si se sabe cuál es la causa. Ver http://codepad.org/nI0vCx4L – delnan
Muchas gracias, lo entiendo ahora. – julkiewicz
@delnan: el código más corto que causa el error es usar 'x = x' dentro de la función interna :) –