以下代码可以在Python 2.7中运行,但在Python 3.4中会引发异常:
一些情况下,
File "/home/sean/dev/ving/meridian/venv/src/django-testmigrate/django_testmigrate/base.py", line 70, in __getattr__
if e:
UnboundLocalError: local variable 'e' referenced before assignment
e
虽然在同一个函数的最上方被赋值了。我猜想在 Python 3 中有一些新的作用域规则,但我找不到任何参考资料。
以下是代码:
def __getattr__(self, name):
e = None
if not self._store:
raise AttributeError("'%s' object has no attribute '%s'" % (self.__class__.__name__, name))
for state, scope in reversed(list(self._store.items())):
try:
val = getattr(scope, name)
except AttributeError as e:
continue
else:
e = None
# get fresh instance
if state != self._current_state and isinstance(val, models.Model):
model_meta = val.__class__._meta
model_class = self._current_state.get_model(model_meta.app_label, model_meta.model_name)
val = model_class.objects.get(pk=val.pk)
# add this value to the current scope
setattr(self, name, val)
break
if e: # error raised here
raise AttributeError("'%s' object has no attribute '%s'" % (self.__class__.__name__, name))
return val
更新:
我通过修改我的代码,使其正常工作,具体如下:
except AttributeError as ex:
# needed for Python 3 compatibility
e = ex
continue
一些情况下,
except...as
竟然会从局部作用域中删除变量 e
。对我来说看起来像是Python的一个bug。
except
子句中引发新的AttributeError
异常不就行了吗? - kindall