How to check if an object is a generator object in python?
在Python中,如何检查对象是否是生成器对象?
尝试这个
1 | >>> type(myobject, generator) |
给出了错误-
1 2 3 | Traceback (most recent call last): File"<stdin>", line 1, in <module> NameError: name 'generator' is not defined |
(我知道我可以检查对象是否有一个
可以使用以下类型的GeneratorType:
1 2 3 4 5 6 | >>> import types >>> types.GeneratorType <class 'generator'> >>> gen = (i for i in range(10)) >>> isinstance(gen, types.GeneratorType) True |
你是说发电机的功能?使用
编辑:
如果你想要一个生成器对象,你可以使用inspect.isgenerator,正如jab在他的评论中指出的那样。
我认为区分发电机功能和发电机(发电机功能的结果)很重要:
1 2 3 4 5 6 7 | >>> def generator_function(): ... yield 1 ... yield 2 ... >>> import inspect >>> inspect.isgeneratorfunction(generator_function) True |
调用generator_函数不会产生正常结果,甚至不会在函数本身执行任何代码,结果将是名为generator的特殊对象:
1 2 3 | >>> generator = generator_function() >>> generator <generator object generator_function at 0x10b3f2b90> |
所以它不是发电机功能,而是发电机:
1 2 3 4 5 6 | >>> inspect.isgeneratorfunction(generator) False >>> import types >>> isinstance(generator, types.GeneratorType) True |
发电机功能不是发电机:
1 2 | >>> isinstance(generator_function, types.GeneratorType) False |
仅作为参考,实际调用函数体时会使用生成器,例如:
1 2 | >>> list(generator) [1, 2] |
另请参见在python中,是否有一种方法在调用函数之前检查函数是否是"生成器函数"?
如果要检查纯生成器(即"Generator"类的对象),则
1 2 | def isgenerator(iterable): return hasattr(iterable,'__iter__') and not hasattr(iterable,'__len__') |
1 2 3 4 5 6 7 | >>> import inspect >>> >>> def foo(): ... yield 'foo' ... >>> print inspect.isgeneratorfunction(foo) True |
I know I can check if the object has a next method for it to be a generator, but I want some way using which I can determine the type of any object, not just generators.
不要这样做。这只是一个非常非常糟糕的主意。
相反,请执行以下操作:
1 2 3 4 5 6 7 | 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循环体也有
或者(3)像这样的东西来区分漂浮在周围的所有这些
1 2 3 4 5 6 7 8 9 10 11 | 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)修复应用程序的其他部分以适当地提供生成器。这通常比所有这些都简单。
如果您使用的是Tornado Web服务器或类似服务器,您可能会发现服务器方法实际上是生成器,而不是方法。这使得调用其他方法变得困难,因为yield在方法内部不起作用,因此需要开始管理链接生成器对象的池。管理链接生成器池的一个简单方法是创建一个帮助函数,例如
1 2 3 4 5 6 7 | def chainPool(*arg): for f in arg: if(hasattr(f,"__iter__")): for e in f: yield e else: yield f |
现在编写链生成器,如
1 | [x for x in chainPool(chainPool(1,2),3,4,chainPool(5,chainPool(6)))] |
产出产出
1 | [1, 2, 3, 4, 5, 6] |
如果您希望使用生成器作为线程备选方案或类似方案,这可能是您想要的。