1、遍历globals()
执行结果:出错,dictionary changed size during iteration
出错原因:程序执行到“for name, obj in iteritems(globals())”时,将name,obj加入到globals()中,因此字典的大小改变
iteritems = lambda d, *args, **kwargs: iter(d.items(*args, **kwargs))
print(globals())
# 出错:dictionary changed size during iteration
# 原因,程序执行到下一行时,将name,obj加入到globals()中,因此字典的大小改变
for name, obj in iteritems(globals()):
print(name)
print(globals())
2、定义函数,在函数中遍历
执行结果:成功
原因:函数中globals()不会变化
iteritems = lambda d, *args, **kwargs: iter(d.items(*args, **kwargs))
# 出错:dictionary changed size during iteration
# 原因,程序执行到下一行时,将name,obj加入到globals()中,因此字典的大小改变
'''
for name, obj in iteritems(globals()):
print(name)
print(globals())
'''
# 解决方法:定义函数,将代码包括在里面,函数中globals()不会变化
def _find_exceptions():
for name, obj in iteritems(globals()):
print(name)
_find_exceptions()
3、函数中的locals()
iteritems = lambda d, *args, **kwargs: iter(d.items(*args, **kwargs))
# 出错:dictionary changed size during iteration
# 原因,程序执行到下一行时,将name,obj加入到globals()中,因此字典的大小改变
'''
for name, obj in iteritems(globals()):
print(name)
print(globals())
'''
# 解决方法:定义函数,将代码包括在里面,函数中globals()不会变化,locals()一直在变化
def _find_exceptions():
a = 0
for name, obj in iteritems(globals()):
print(locals())
# print(name)
a +=1
_find_exceptions()
执行后输出结果:
{'a': 0, 'name': '__name__', 'obj': '__main__'}
{'a': 1, 'name': '__doc__', 'obj': None}
{'a': 2, 'name': '__package__', 'obj': None}
{'a': 3, 'name': '__loader__', 'obj': <_frozen_importlib_external.sourcefileloader object at>}
{'a': 4, 'name': '__spec__', 'obj': None}
{'a': 5, 'name': '__annotations__', 'obj': {}}
{'a': 6, 'name': '__builtins__', 'obj': }
{'a': 7, 'name': '__file__', 'obj': 'F:/2018/python/review/project/Flask_01/globals于locals之locals.py'}
{'a': 8, 'name': '__cached__', 'obj': None}
{'a': 9, 'name': 'iteritems', 'obj': at 0x00300810>}
{'a': 10, 'name': '_find_exceptions', 'obj': }
4、程序参考
参考werkzeug源码中exceptions.py中的:
iteritems = lambda d, *args, **kwargs: iter(d.items(*args, **kwargs))
def _find_exceptions():
for name, obj in iteritems(globals()):
try:
is_http_exception = issubclass(obj, HTTPException)
except TypeError:
is_http_exception = False
if not is_http_exception or obj.code is None:
continue
__all__.append(obj.__name__)
old_obj = default_exceptions.get(obj.code, None)
if old_obj is not None and issubclass(obj, old_obj):
continue
default_exceptions[obj.code] = obj
_find_exceptions()
del _find_exceptions