问题:如何检查对象是否是python中的生成器对象?
在python中,如何检查对象是否为生成器对象?
试试这个-
>>> type(myobject, generator)
给出错误-
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
NameError: name 'generator' is not defined
(我知道我可以检查对象是否具有next
将其用作生成器的方法,但我想使用某种方法可以确定任何对象的类型,而不仅仅是生成器。)
回答 0
您可以从以下类型使用GeneratorType:
>>> import types
>>> types.GeneratorType
<class 'generator'>
>>> gen = (i for i in range(10))
>>> isinstance(gen, types.GeneratorType)
True
回答 1
回答 2
我认为区分生成器函数和生成器(生成器函数的结果)很重要:
>>> 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]
回答 3
inspect.isgenerator
如果要检查纯生成器(即“生成器”类的对象),则该函数很好。但是,False
如果您检查例如izip
iterable ,它将返回。检查通用生成器的另一种方法是使用此函数:
def isgenerator(iterable):
return hasattr(iterable,'__iter__') and not hasattr(iterable,'__len__')
回答 4
您可以使用输入模块中的Iterator或更具体地说,使用Generator 。
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
>>> import inspect
>>>
>>> def foo():
... yield 'foo'
...
>>> print inspect.isgeneratorfunction(foo)
True
回答 6
我知道我可以检查对象是否具有将其用作生成器的下一个方法,但是我想使用某种方法可以确定任何对象的类型,而不仅仅是生成器。
不要这样 这只是一个非常非常糟糕的主意。
相反,请执行以下操作:
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)使用嵌套的try块。
或(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)修复应用程序的其他部分,以适当地提供生成器。这通常比所有这些都简单。
回答 7
如果您使用的是Tornado Web服务器或类似服务器,则可能会发现服务器方法实际上是生成器,而不是方法。这使得很难调用其他方法,因为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
(我知道这是一篇老文章。)无需导入模块,您可以在程序开始时声明一个对象以进行比较:
gentyp= type(1 for i in "")
...
type(myobject) == gentyp