很明显4G内存要一次性的加载大小考虑为8G的文件是不现实的,遇到这种情况必须多次读取并分批处理。在Python中读取文件可以先通过函数获取文件open
对象,在读取文件时,可以通过read
方法的size
参数指定读取的大小,也可以通过seek
方法的offset
参数指定读取的位置,这样就可以控制单次读取数据的字节数和总字节数。除此之外,可以使用内置函数iter
将文件对象处理成迭代器对象,每次只读取少量的数据进行处理,代码大致写法如下所示。
with open('...', 'rb') as file: for data in iter(lambda: file.read(2097152), b''): pass
在Linux系统上,可以通过split
命令将大文件切割为小片,然后通过读取切割后的小文件对数据进行处理。例如下面的命令将调用的大文件切割为大小filename
为512M的多个文件。
split -b 512m filename
如果愿意,也可以将名为filename
的文件切割为10个文件,命令如下所示。
split -n 10 filename
扩展:外部排序跟上面的情况非常类似,由于处理的数据不能一次导入内存,只能放在读写器较慢的外存储器(通常是硬盘)上。“排序归并算法”就是一种常用的外部排序策略。在排序阶段,先读入能放置内存中的数据,将其排序排序到一个临时文件,依此进行,将待排序组织数据为多个小区的临时文件,然后在归并阶段将这些临时文件组合成一个大的小区文件,这个大的小区文件就是排序的结果。
问题41:说说你对Python中模块和包的理解。
每个Python文件就是一个模块,而保存这些文件的文件夹就是一个包,这个Python包的文件夹必须作为一个名为的文件,否则__init__.py
无法导入这个包。通常一个文件夹下还可以有子文件夹,这意味着一个包下还可以有子包,子包中的__init__.py
不是必须的。模块和包解决了Python中命名冲突的问题,不同的包下可以有同名的模块,不同的模块下可以有同名的变量、函数或类。在Python中可以使用import
或from ... import ...
来导入包和模块,在导入的时候还可以使用as
关键字对包、模块、类、函数、变量等进行别名,从而彻底解决编程尤其是多人协作团队开发时的命名冲突问题。