给定一个生成器对象,是否可以测试它是否是由给定的生成器创建的?也许更好的说法,是否有可能测试我们的发电机的"类型"?由于生成器对象具有类型generator,因此使用type或isinstance不执行测试.
请考虑以下代码:
>>> 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>
Run Code Online (Sandbox Code Playgroud)
需要注意的是,如果我是使用迭代器类,而不是实现发电机,那么这两个type和isinstance会的工作,因为生成的对象将是由迭代器类所给出的类型:
>>> class gen():
... def __next__(self):
... return 1
...
>>> f = gen()
>>> type(f) is gen
True
>>> isinstance(f, gen)
True
Run Code Online (Sandbox Code Playgroud)
是否可以通过使用yield?创建的生成器实现简单(不使用将数据包包装在类中,或使用装饰器)等方面实现相同的功能?
生成函数的名称(如果有)__name__作为字符串存储在属性中.如果字符串是你需要的全部,那么你已经完成了.
要获得实际的功能对象,它很复杂.生成器本身不保存对函数对象的任何引用,逻辑使用对代码对象的引用进行操作.
function object (`gen1`) -----> <code object >
^
generator object (`g1`) -----------?
Run Code Online (Sandbox Code Playgroud)
使用生成器函数的原始名称,您可以想象使用getattr包含模块来尝试检索原始函数.这种方法不一定可靠:这里假设函数对象仍然存在并且仍然绑定到该名称.但是,该名称可能已被删除或反弹.在CPython中,如果引用计数减少到0,该函数也可能已被垃圾收集.
| 归档时间: |
|
| 查看次数: |
116 次 |
| 最近记录: |