TypeError: 'NoneType' object is not iterable when applying decorator to generator

随声附和 提交于 2019-12-11 01:27:58

问题


I have a decorator function which I want to apply to both normal function and a generator. When applied to the normal function, it works properly. However, when applied to the generator, the iteration loop inside the decorator is executed till the end, but after that the script throws an error:

TypeError: 'NoneType' object is not iterable

and exits the script.

def decor(func):
    def wrapper(*args, **kwargs):
        func_name = func.__name__
        is_generator = "_generator" in func_name
        if is_generator:
            for item in func(*args, **kwargs):
                print(item)
        else:
            res = func(*args, **kwargs)
            print(res)
    return wrapper

@decor            
def f():
    return "a"

@decor    
def f_generator():
    for i in range(2):
        yield "b"

f()

""" Output: a """

for item in f_generator():
    print ("Processing item ", item)

"""
Output:
b
b
Traceback (most recent call last):
  File "test.py", line 27, in <module>
      for item in f_generator():
TypeError: 'NoneType' object is not iterable
"""

Furthermore, when the decorator is applied to the generator, the print ("Processing item ", item) of the external generator call is not executed. Once I remove the decorator from the generator, I can call the generator and it functions properly.

How do I fix the problem so that I can apply the decorator to the generator and get it working without an error? Trying to handle the error with an exception takes away the error and the script is executed entirely, but then the print ("Processing item ", item) is still not being executed.


回答1:


When you add @decorator, f_generator() in for item in f_generator(): is actually decor(f_generator). Since decor() does not yield or return anything, it's not iterable itself, you should add yield item around for item in func(*args, **kwargs):




回答2:


the problem is with your last loop. you are iterating over the function wrapper since that is what you get when calling f_generator() and wrapper is not an iterator.

you can simply replace the last for loop with a call to your function. this is a nice tutorial i learned a lot from about decorators



来源:https://stackoverflow.com/questions/54003962/typeerror-nonetype-object-is-not-iterable-when-applying-decorator-to-generato

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!