Python:生成器对象的属性
在生成器对象上创建属性是否可能?
这里有一个非常简单的例子:
def filter(x):
for line in myContent:
if line == x:
yield x
现在假设我有很多这样的过滤生成器对象在使用……可能其中一些是匿名的……我想在之后回去查看它们在过滤什么。我有没有办法可以 a) 查询生成器对象的 x 值,或者 b) 设置一个属性,给 x 赋值,以便我可以在之后查询?
谢谢
7 个回答
3
如果你想要检查它们以便调试,那么下面这个函数会对你有帮助:
import inspect
def inspect_generator(g):
sourcecode = open(g.gi_code.co_filename).readlines()
gline = g.gi_code.co_firstlineno
generator_code = inspect.getblock(sourcecode[gline-1:])
output = "Generator %r from %r\n" % (g.gi_code.co_name, g.gi_code.co_filename)
output += "".join("%4s: %s" % (idx+gline, line) for idx, line in enumerate(generator_code))
output += "Local variables:\n"
output += "".join("%s = %r\n" % (key,value) for key,value in g.gi_frame.f_locals.items())
return output
print inspect_generator(filter(6))
"""Output:
Generator 'filter' from 'generator_introspection.py'
1: def filter(x):
2: for line in myContent:
3: if line == x:
4: yield x
Local variables:
x = 6
"""
如果你想要检查它们是为了实现某些功能,那么使用实现了迭代器协议的类可能会更好。
19
是的。
class Filter( object ):
def __init__( self, content ):
self.content = content
def __call__( self, someParam ):
self.someParam = someParam
for line in self.content:
if line == someParam:
yield line
8
很遗憾,生成器对象(也就是调用生成器函数后得到的结果)不支持添加任意属性。不过,你可以通过使用一个外部的字典来解决这个问题,因为生成器对象可以作为字典的键。也就是说,如果你想这样做:
a = filter(23)
b = filter(45)
...
a.foo = 67
...
x = random.choice([a,b])
if hasattr(x, 'foo'): munge(x.foo)
你可以改成这样:
foos = dict()
a = filter(23)
b = filter(45)
...
foos[a] = 67
...
x = random.choice([a,b])
if x in foos: munge(foos[x])
如果你需要更复杂的功能,可以考虑使用类来代替生成器(毕竟,类中的一个或多个方法可以是生成器)。