如何检查一个对象是否是python中的生成器对象?

在python中,如何检查对象是否为生成器对象?

试着——

>>> type(myobject, generator)

给出错误-

Traceback (most recent call last):
File "<stdin>", line 1, in <module>
NameError: name 'generator' is not defined

(我知道我可以检查对象是否有next方法作为生成器,但我想要某种方法来确定任何对象的类型,而不仅仅是生成器。)

66854 次浏览

你是说发电机函数?使用inspect.isgeneratorfunction

编辑:

如果你想要一个生成器对象,你可以使用JAB在他的评论中指出的inspect.isgenerator

你可以从类型中使用GeneratorType:

>>> import types
>>> types.GeneratorType
<class 'generator'>
>>> gen = (i for i in range(10))
>>> isinstance(gen, types.GeneratorType)
True

我知道我可以检查对象是否有下一个方法,它是一个生成器,但我想用一些方法,我可以确定任何对象的类型,而不仅仅是生成器。

不要这样做。这是个非常非常糟糕的主意。

相反,这样做:

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

在不太可能发生的情况下,循环体也有__abc0,有几个选择:(1)定义一个函数来限制错误的范围,或(2)使用嵌套的试一试块。

或者(3)类似这样的东西来区分所有漂浮在周围的__abc。

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)修复应用程序的其他部分,以适当地提供生成器。这通常比这些都简单。

>>> import inspect
>>>
>>> def foo():
...   yield 'foo'
...
>>> print inspect.isgeneratorfunction(foo)
True

如果你想检查纯生成器(即“generator”类的对象),inspect.isgenerator函数是很好的。然而,如果你检查,例如,izip迭代对象,它将返回False。检查泛化生成器的另一种方法是使用这个函数:

def isgenerator(iterable):
return hasattr(iterable,'__iter__') and not hasattr(iterable,'__len__')

我认为区分发生器功能发电机(生成器函数的结果)是很重要的:

>>> 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>

所以它不是generator函数,而是generator:

>>> inspect.isgeneratorfunction(generator)
False


>>> import types
>>> isinstance(generator, types.GeneratorType)
True

generator函数不是generator:

>>> isinstance(generator_function, types.GeneratorType)
False

仅供参考,实际调用函数体将通过消耗生成器发生,例如:

>>> list(generator)
[1, 2]

另见在python中,是否有一种方法来检查一个函数是否是“生成器函数”?在调用它之前?

如果你正在使用tornado webserver或类似的服务器,你可能会发现服务器方法实际上是生成器而不是方法。这使得很难调用其他方法,因为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]

这可能是你想要的,如果你想使用生成器作为线程替代品或类似的。

你可以使用迭代器,或者更具体地说,使用打字模块中的生成器。

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

(我知道这是一个旧帖子。)不需要导入模块,你可以在程序开始时声明一个对象进行比较:

gentyp= type(1 for i in "")
...
type(myobject) == gentyp

这是一个有点老的问题,然而我正在为自己寻找类似的解决方案,但对于异步生成器类,所以你可能会发现这是有帮助的。

基于utdemir的回复:

import types
isinstance(async_generator(), types.AsyncGeneratorType)