我们可以使用python变量来保存整个文件吗?

时间:2009-09-16 15:03:20

标签: python file variables

如果我们知道所有文件都将加载到内存中,我们可以负担得起, 在python变量中加载整个文件(可能是二进制文件)有什么缺点(如果有的话)或限制(如果有的话)。如果这在技术上是可行的,那么应该避免这种情况,为什么?

关于文件大小问题,应该限制此解决方案的最大大小?为什么?

实际加载代码可以是this stackoverflow entry中提出的代码。

示例代码为:

def file_get_contents(filename):
    with open(filename) as f:
        return f.read()

content = file_get_contents('/bin/kill')

... code manipulating 'content' ...

[编辑] 想到的代码操作(但可能不适用)是标准列表/字符串运算符(方括号,'+'符号)或一些字符串运算符('len','in'运算符,'count','endswith'/ 'startswith','split','translation'......)。

6 个答案:

答案 0 :(得分:11)

  • 是的,你可以
  • 唯一的缺点是内存使用情况,如果文件很大,也可能提速。
  • 文件大小应限制在内存中的空间。

一般来说,有更好的方法可以做到这一点,但对于一次性脚本,你知道内存不是问题,当然。

答案 1 :(得分:8)

虽然你得到了很好的回答,但似乎没有人回答你问题的这一部分(正如你在问题中提出许多问题时经常发生的那样;)......:

  

关于文件大小问题,关于什么   这个解决方案应该是最大尺寸   有限?为什么?

最重要的是,这个特定的Python进程实际上可以使用(所谓的“工作集”)多少物理RAM,而不会过度惩罚整个系统性能的其他方面。如果你的“工作集”超过了物理RAM,那么你将进行分页和交换到磁盘,你的性能会迅速下降(直到所谓的“颠簸”状态基本上所有可用周期都会进入获取页面进出的任务,实际工作量可以忽略不计。)

除此之外,一个相当适度的数量(一般来说最多几MB)可能会被可执行代码(Python自己的可执行文件,DLL或.so)以及字节码和一般支持数据结构所占用。记忆中积极需要的;在一个没有做其他重要或紧急任务的典型现代机器上,与整体可用的数十亿字节相比,你几乎可以忽略这一开销(虽然嵌入式系统的情况可能不同等)。

所有其他内容都可用于您的数据 - 包括您正在读入内存的此文件,以及任何其他重要数据结构。文件数据的“修改”通常可以(暂时)占用文件内容大小的两倍(如果你把它保存在一个字符串中) - 当然,如果你保留一份副本,那么更多旧数据以及制作新修改的副本/版本。

因此,对于典型的现代32位机器上的“只读”使用,例如总体上2GB的RAM,读入内存(比方说)1.5 GB应该没问题;但是如果你正在进行“修改”,它必须大大小于1 GB(如果你在内存中有其他重要的数据结构,那就更少了!)。当然,在具有64位构建的Python,64位操作系统和16 GB RAM的专用服务器上,实际限制在非常不同之前 - 实际上大致与可用RAM的大小不同。

例如,King James的圣经文本可下载here(解压缩)大约4.4 MB;因此,在具有2 GB RAM的计算机中,您可以在内存中保留大约400个略微修改过的副本(如果没有其他请求内存),但是,在具有16(可用且可寻址)GB的RAM的计算机中,您可以保留超过3000份这样的副本。

答案 2 :(得分:4)

with open(filename) as f:

这仅适用于Unix上的Python 2.x.它不会在Python 3.x或Windows上执行您所期望的操作,因为它们在文本和二进制文件之间产生了很大的区别。最好指定文件是二进制文件,如下所示:

with open(filename, 'rb') as f:

这将关闭Windows上的操作系统CR / LF转换,并强制Python 3.x返回字节数组而不是Unicode字符。

关于你的其余问题,我同意Lennart Regebro的(未经编辑的)答案。

答案 3 :(得分:3)

你可以遇到的唯一问题是内存消耗:Python中的字符串是不可变的。因此,当您需要更改字节时,需要复制旧字符串:

new = old[0:pos] + newByte + old[pos+1:]

这需要最多三倍于old的内存。

您可以使用array代替字符串。如果您需要修改内容,这些可以提供更好的性能,您可以从字符串中轻松创建它们。

答案 4 :(得分:1)

您还可以使用Python的v3功能:

>>> ''.join(open('htdocs/config.php', 'r').readlines())
"This is the first line of the file.\nSecond line of the file"

在此处阅读更多http://docs.python.org/py3k/tutorial/inputoutput.html

答案 5 :(得分:0)

是的,您可以 - 提供的文件足够小 - 。

甚至非常pythonic进一步将read()的返回转换为任何容器/可迭代类型,比如string.split(),以及相关的函数编程功能,以继续“立即”处理文件。 / p>