我试图编写一系列写入临时文件的函数,然后使用写入的文件执行操作。我试图了解文件是如何处理的。
我想在摘要中做的是:
def create_function(inputs):
# create temp file, write some contents
def function1(file):
# do some stuff with temp file
def function2(file):
# do some other stuff with temp file
所以我可以做类似的事情:
my_file = create_function(my_inputs)
function1(my_file)
function2(my_file)
所以这就是我实际做过的事情:
def db_cds_to_fna(collection, open_file):
"""
This pulls data from a mongoDB and writes it to a temporary file - just writing an arbitrary string doesn't alter my question (I'm pretty sure)
"""
for record in db[collection].find({"type": "CDS"}):
open_file.write(">{}|{}|{}\n{}\n".format(
collection,
record["_id"],
record["annotation"],
record["dna_seq"]
)
)
return open_file.name
def check_file(open_file):
lines = 0
for line in open_file:
if lines < 5:
print line
lines += 1
else:
break
使用此代码,如果我运行以下内容:
from tempfile import NamedTemporaryFile
tmp_file = NamedTemporaryFile()
tmp_fna = db_cds_to_fna('test_collection', tmp_file)
check_file(tmp_file)
此代码运行,但实际上并未打印任何内容。但是文件显然是在那里写的,因为如果我运行print Popen(['head', tmp_fna], stdout=PIPE)[0]
,我会得到文件的预期开头。或者,如果我更改check_file()
以接受tmp_file.name
并在函数内执行with open(tmp_file.name, 'r')...
,则可行。
所以问题1是 - 为什么我可以写tmp_file
,但是不能重新打开它就能从不同的函数中读取它?
现在,我真正想做的是在tmp_file = NamedTemporaryFile()
函数中使用db_cds_to_fna()
,但是当我尝试并运行时:
tmp_fna = db_cds_to_fna('test_collection')
check_file(tmp_file)
我收到错误No such file or folder
所以问题2是:有没有办法保留临时文件以供另一个函数使用?我知道如何将文件写入指定的路径然后将其删除,但我怀疑是否有内置的方法可以做到这一点,我想学习。
答案 0 :(得分:1)
您正在写入该文件,但之后您正在尝试从写入结束时读取它。在开始阅读之前添加seek
,以返回文件的开头:
def check_file(open_file):
lines = 0
open_file.seek(0)
for line in open_file:
if lines < 5:
print line
lines += 1
else:
break
关于第二个问题,请注意NamedTemporaryFile
的作用类似于TemporaryFile
:
它会在关闭时被销毁(包括隐含的 当对象被垃圾收集时关闭。)
如果在函数中打开文件然后返回,则文件超出范围并将被关闭并进行垃圾回收。您需要保持对文件对象的引用,以防止它被收集。您可以通过从函数返回文件对象来执行此操作(并确保将其分配给某些内容)。这是一个简单的例子:
def mycreate():
return NamedTemporaryFile()
def mywrite(f, i):
f.write(i)
def myread(f):
f.seek(0)
return f.read()
f = mycreate() # 'f' is now a reference to the file created in the function,
# which will keep it from being garbage collected
mywrite(f, b'Hi')
myread(f)