Python tempfile: 是我使用不当还是有问题?
我有一个小的Python脚本,想用tempfile模块来创建一个临时文件。但是它的表现和我预期的不一样,我不知道自己哪里出错了,或者这是不是个bug:
Python 2.7.2 (default, Jun 12 2011, 15:08:59) [MSC v.1500 32 bit (Intel)] on win32
Type "help", "copyright", "credits" or "license" for more information.
>>> import tempfile
>>> tmp = tempfile.TemporaryFile()
>>> tmp.read()
''
>>> tmp.write('test')
>>> tmp.read()
'P\xf6D\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\ [ommitted]'
另外,我尝试了只用文本模式,但结果还是很奇怪:
Python 2.7.2 (default, Jun 12 2011, 15:08:59) [MSC v.1500 32 bit (Intel)] on win32
Type "help", "copyright", "credits" or "license" for more information.
>>> import tempfile
>>> tmp = tempfile.TemporaryFile('w+t')
>>> tmp.read()
''
>>> tmp.write('test')
>>> tmp.read()
'\x00\xa5\x8b\x02int or long, hash(a) is used instead.\n i\x10 [ommitted]'
>>> tmp.seek(0)
>>> tmp.readline()
'test\x00\xa5\x8b\x02int or long, hash(a) is used instead.\n'
任何帮助都非常感谢!
补充信息:我使用的是Python 2.7.2(32位),来自当前的Python XY版本,运行在Windows 7企业版x64机器上。在一次测试中,Python在我的临时目录D:\temp\myusername下创建了一个名为“tmpvyocxj”的临时文件,同时还有其他几个Python进程在运行。我是直接输入命令的,还没有尝试在脚本中重现这个问题。即使没有其他Python进程在运行,这种表现也没有改变。
更新: 这种情况不仅限于tempfile模块,普通的file.read()和file.write()操作也会出现同样的问题。根据CPython的开发者说,这两个函数只是调用了底层的libc fread()例程。在C标准中,写入后再读取而不进行寻址或刷新,其具体行为是未定义的,也就是说,每个实现可能会导致不同的结果。
2 个回答
0
在Ubuntu系统上无法重现这个问题,使用的是Python 2.7.1版本。
Python 2.7.1+ (r271:86832, Apr 11 2011, 18:05:24)
[GCC 4.5.2] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import tempfile
>>> tmp = tempfile.TemporaryFile('w+t')
>>> tmp.read()
''
>>> tmp.write('test')
>>> tmp.read()
''
>>> tmp.seek(0)
>>> tmp.readline()
'test'
>>>
8
我在Windows XP上用Python 2.7.1复现了这个问题。
看起来这是一个错误,只有在你尝试读取数据但没有先进行定位时才会出现。
也就是说:
>>> tmp.write('test')
>>> tmp.seek(0)
>>> tmp.read()
'test'
和
>>> tmp.write('test')
>>> tmp.read()
'x\x01\x98\x00pfile.pyR\x05\x00\x00\x00G\x01\x00\x00s\x12 [blah blah blah]'
>>> tmp.seek(0)
>>> tmp.read()
'testx\x01\x98\x00pfile.pyR\x05\x00\x00\x00G\x01\x00\x00s\x12 [blah blah blah]'
补充:
为了好玩,我还检查了:
- Windows 7,同样是2.7.1(和我XP上的版本是一样的),结果和XP上看到的行为是一样的。
- Cygwin版本2.6.5,这个错误没有出现。