在Python中,是否有任何方法可以测试generator对象以找出是哪个generator创建了它?

2024-09-28 23:19:56 发布

您现在位置:Python中文网/ 问答频道 /正文

给定一个生成器对象,是否可以测试它是否由给定的生成器创建?也许更好地说,有可能测试什么类型的发电机,我们有?由于生成器对象具有类型generator,因此使用typeisinstance进行测试将不起作用。你知道吗

考虑以下代码:

>>> def gen1():
...     yield 1
... 
>>> def gen2():
...     yield 2
... 
>>> g1 = gen1()
>>> g2 = gen2()
>>> 
>>> def do_something(f):
...     # need to know if f is a gen1 generator or a gen2 generator here
...     # isinstance(f, gen1)  raises a TypeError since gen1 is not a type
...     # type(f) is gen1 returns false
...     print(f)
... 
>>> do_something(g1)
<generator object gen1 at 0x100dcb370>
>>> do_something(g2)
<generator object gen2 at 0x100dcb3c0>

请注意,如果改用迭代器类实现生成器,则typeisinstance都可以工作,因为生成的对象将是迭代器类给定的类型:

>>> class gen():
...     def __next__(self):
...          return 1
... 
>>> f = gen()
>>> type(f) is gen
True
>>> isinstance(f, gen)
True

对于使用yield创建的生成器,是否可以简单地实现相同的功能(例如,不必在类中包装生成器,或者使用装饰器)?你知道吗


Tags: 对象类型isdeftypegeneratordosomething
1条回答
网友
1楼 · 发布于 2024-09-28 23:19:56

生成函数的名称(如果有)作为字符串存储在__name__属性中。如果你只需要这根绳子,那你就完了。你知道吗

要得到实际的函数对象,这很复杂。生成器本身不包含对函数对象的任何引用,并且逻辑使用对代码对象的引用进行操作。你知道吗

function object (`gen1`)   -> <code object >
                                    ^
generator object (`g1`)       -╯

使用生成器函数的原始名称,您可以在包含模块上使用getattr来尝试检索原始函数。这种方法不一定可靠:这里假设函数对象仍然存在,并且仍然绑定到该名称。但是,名称可能已被删除或反弹。在CPython中,如果引用计数减少到0,该函数也可能已经被垃圾收集。你知道吗

相关问题 更多 >