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 0x0032DDD0>} {'a': 4, 'name': '__spec__', 'obj': None} {'a': 5, 'name': '__annotations__', 'obj': {}} {'a': 6, 'name': '__builtins__', 'obj': <module 'builtins' (built-in)>} {'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': <function <lambda> at 0x00300810>} {'a': 10, 'name': '_find_exceptions', 'obj': <function _find_exceptions at 0x0082FE88>}
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