在python中,如何检查对象是否是生成器对象?
试试这个 -
>>> type(myobject, generator)
给出错误 -
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
NameError: name 'generator' is not defined
(我知道我可以检查对象是否有next
方法作为生成器,但我想用某种方法来确定任何对象的类型,而不仅仅是生成器。)
答案 0 :(得分:181)
您可以使用以下类型的GeneratorType:
>>> import types
>>> types.GeneratorType
<class 'generator'>
>>> gen = (i for i in range(10))
>>> isinstance(gen, types.GeneratorType)
True
答案 1 :(得分:32)
你的意思是发电机功能?使用inspect.isgeneratorfunction
。
编辑:
如果你想要一个生成器对象,你可以按照JAB在他的评论中指出的那样使用inspect.isgenerator。
答案 2 :(得分:16)
我认为区分生成器函数和生成器(生成器函数的结果)非常重要:
>>> def generator_function():
... yield 1
... yield 2
...
>>> import inspect
>>> inspect.isgeneratorfunction(generator_function)
True
调用generator_function不会产生正常结果,它甚至不会在函数本身执行任何代码,结果将是名为 generator 的特殊对象:
>>> generator = generator_function()
>>> generator
<generator object generator_function at 0x10b3f2b90>
所以它不是生成器函数,而是生成器:
>>> inspect.isgeneratorfunction(generator)
False
>>> import types
>>> isinstance(generator, types.GeneratorType)
True
和生成器功能不是生成器:
>>> isinstance(generator_function, types.GeneratorType)
False
仅供参考,函数体的实际调用将通过消耗生成器来实现,例如:
>>> list(generator)
[1, 2]
另见In python is there a way to check if a function is a "generator function" before calling it?
答案 3 :(得分:11)
如果要检查纯生成器(即“生成器”类的对象),inspect.isgenerator
函数就可以了。但是,如果您检查例如False
可迭代,它将返回izip
。检查通用生成器的另一种方法是使用此函数:
def isgenerator(iterable):
return hasattr(iterable,'__iter__') and not hasattr(iterable,'__len__')
答案 4 :(得分:4)
您可以使用迭代器或更具体地说,使用typing模块中的生成器。
from typing import Generator, Iterator
g = (i for i in range(1_000_000))
print(type(g))
print(isinstance(g, Generator))
print(isinstance(g, Iterator))
<class 'generator'>
True
True
答案 5 :(得分:2)
我知道我可以检查对象是否有下一个方法让它成为一个生成器,但我想用某种方法来确定任何对象的类型,而不仅仅是生成器。
不要这样做。这只是一个非常非常糟糕的主意。
相反,这样做:
try:
# Attempt to see if you have an iterable object.
for i in some_thing_which_may_be_a_generator:
# The real work on `i`
except TypeError:
# some_thing_which_may_be_a_generator isn't actually a generator
# do something else
如果 for 循环的主体也有TypeError
s,则有几种选择:(1)定义一个函数来限制错误的范围,或者(2)使用嵌套的尝试块。
或(3)这样的东西可以区分所有这些浮动的TypeError
。
try:
# Attempt to see if you have an iterable object.
# In the case of a generator or iterator iter simply
# returns the value it was passed.
iterator = iter(some_thing_which_may_be_a_generator)
except TypeError:
# some_thing_which_may_be_a_generator isn't actually a generator
# do something else
else:
for i in iterator:
# the real work on `i`
或(4)修复应用程序的其他部分以适当地提供生成器。这通常比所有这些都简单。
答案 6 :(得分:2)
>>> import inspect
>>>
>>> def foo():
... yield 'foo'
...
>>> print inspect.isgeneratorfunction(foo)
True
答案 7 :(得分:1)
如果您使用龙卷风网络服务器或类似网站,您可能会发现服务器方法实际上是生成器而不是方法。这使得调用其他方法变得困难,因为yield在方法内部不起作用,因此您需要开始管理链接的生成器对象池。管理链式生成器池的一种简单方法是创建帮助函数,例如
def chainPool(*arg):
for f in arg:
if(hasattr(f,"__iter__")):
for e in f:
yield e
else:
yield f
现在编写链式生成器,如
[x for x in chainPool(chainPool(1,2),3,4,chainPool(5,chainPool(6)))]
生成输出
[1, 2, 3, 4, 5, 6]
如果您希望将生成器用作线程替代或类似的,那么这可能是您想要的。
答案 8 :(得分:1)
(我知道这是一篇老文章。)不需要导入模块,您可以在程序开始时声明一个对象以进行比较:
gentyp= type(1 for i in "")
...
type(myobject) == gentyp