我写了一个读txt文件的类。文件由非空行块(我们称之为“段”)组成,由空行分隔:
line1.1
line1.2
line1.3
line2.1
line2.2
我的第一个实现是读取整个文件并返回一个列表列表,即一个节列表,其中每个节都是一个行列表。 这显然是可怕的记忆。
所以我将它重新实现为一个列表生成器,也就是说,在每个循环中,我的类都将内存中的一个完整部分作为一个列表读取并生成它。
这是更好的,但它仍然有问题的情况下,大段。所以我想知道我是否可以把它作为一个发电机的发电机重新实现?问题是这个类非常通用,它应该能够满足这两个用例:
将一个小文件读入内存,以便多次循环。列表生成器工作正常,因为用户可以调用
列表(MyClass(文件句柄))
但是,生成器的生成器在案例2中不起作用,因为内部对象不会转换为列表。
有什么比实现显式to_list()方法更优雅的方法吗?该方法将生成器转换为列表列表?
一个相当实用的方法是在创建时告诉“生成器的生成器”是生成生成器还是生成列表。虽然这不如让
list
神奇地知道该怎么做那么方便,但它似乎仍然比拥有一个特殊的to_list
函数更舒适。根据
listmode
参数,这可以用于生成生成器或列表。Python2:
Python3:
或者两者兼而有之:
因为生成的对象是
generator functions
,而不仅仅是生成器,所以您需要如果那不起作用,我不知道你在问什么。另外,为什么它会返回一个生成器函数而不是生成器本身?
因为在评论中你说你想避免
list(generator_of_generator_functions)
神秘地崩溃,这取决于你真正想要的是什么。以这种方式覆盖
list
的行为是不可能的:要么存储子生成器元素,要么不存储子生成器元素如果真的发生了崩溃,我建议每次主生成器迭代时都使用主生成器循环耗尽子生成器。这是标准实践,也正是
itertools.groupby
所做的,一个stdlib生成器。例如
正如所承诺的,黑客(对于Python 3,这次是“回合”):
太糟糕了,我都不想解释。
关键是你有一个包装器,可以检测它是否已经被迭代,如果没有,你运行一个
_to_list_hack
,我不骗你,改变__class__
属性。由于布局冲突,我们必须使用
UserList
类并隐藏其所有方法,这只是crud的另一层。基本上,请不要使用这个黑客。不过,你可以把它当作幽默来欣赏。
相关问题 更多 >
编程相关推荐