cam*_*mil 3 python generator python-2.7
我经常使用返回某个类的生成器.我想做的是将生成器类子类化,以便我可以使用适合于生成该类实例的生成器的方法.例如,我想做的一件事就是有一个方法返回一个过滤基础生成器的生成器.
我想做这样的事情:
class Clothes(object):
def __init__(self, generator):
self.generator = generator
def get_red(self):
return (c for c in self.generator if c.color=="red")
def get_hats(self):
return (c for c in self.generator if c.headgear)
Run Code Online (Sandbox Code Playgroud)
我想把衣服当作衣服的集合.我没有对集合进行子类化的原因是我很少想要按原样使用整个服装集合,通常只需要进一步过滤它.但是,我经常需要各种过滤的衣服系列.如果可能的话,我希望Clothes本身就是一个生成器,因为我打算使用它,但是在尝试子类时我遇到了错误types.GeneratorType.
types.GeneratorType
Run Code Online (Sandbox Code Playgroud)
定义为:
def _g():
yield 1
GeneratorType = type(_g())
Run Code Online (Sandbox Code Playgroud)
如你所见,它不是常规的class.
现在,是什么让发电机变得特别?不多.要利用它generator protocol,所有人必须做的就是实现iterator protocol.有一个很好的捷径:next()当你__iter__是一个发电机时,你可以获得免费的.而这正是如何collections.Iterable定义的:
class Iterable(metaclass=ABCMeta):
@abstractmethod
def __iter__(self):
while False:
yield None
@classmethod
def __subclasshook__(cls, C):
if cls is Iterable:
if any("__iter__" in B.__dict__ for B in C.__mro__):
return True
return NotImplemented
Run Code Online (Sandbox Code Playgroud)
所以,只需用它来构建你的发电机.
正如您在前面的问题的评论中所指出的,返回生成器表达式通常是个坏主意.引用PEP 289:
...强烈建议用户在立即使用其参数的函数内使用生成器表达式.对于更复杂的应用程序,完整的生成器定义总是优于范围,生命周期和绑定方面.
本着上述精神,我建议:
__iter__(反过来,可以是生成器)使主类可迭代.get_xxx为迭代的生成器self和yield来自它的特定值例:
class Numbers(object):
def __iter__(self):
for x in range(10):
yield x
def get_odd(self):
for x in self:
if x & 1:
yield x
nums = Numbers()
for x in nums:
print x # 0 1 2 3...
for x in nums.get_odd():
print x # 1 3 5...
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
2053 次 |
| 最近记录: |