如何传递 Python 中的文件、BytesIO、StringIO 以备后用?
How to pass file, BytesIO, StringIO in Python to be used later?
这三个内存或磁盘缓冲区遵循相同的访问模式。我要重点 BytesIO
.
如何传入文件或缓冲区对象供以后使用?
我在以下用例中遇到了很多麻烦:
def get_file_and_metadata():
metadata = {"foo": "bar"}
with io.BytesIO() as f:
f.write(b'content')
f.seek(0)
return f, metadata
f, metadata = get_file_and_metadata()
# Do something with file
pd.read_csv(f, encoding="utf-8")
我怀疑是因为 f.close()
在 return 语句之后是 运行。
with
关键字将在文件脱离上下文后自动关闭文件,即脱离 with 代码块(因此称为上下文管理器)。
相反,创建 file_obj 和 return。
def get_file_and_metadata():
metadata = {"foo": "bar"}
f = io.BytesIO()
f.write(b'content')
f.seek(0)
return f, metadata
f, metadata = get_file_and_metadata()
# Do something with file
print(f.read())
f.close()
del f # to remove it from memory.
当 with
套件终止时,close
是 运行。如果你想传回一个打开的 file-like 对象,你不应该在 with
中打开它。一种选择是完全放弃上下文管理器并将其留给调用者来清理对象。
def get_file_and_metadata():
metadata = {"foo": "bar"}
f = o.BytesIO()
f.write(b'content')
f.seek(0)
return f, metadata
f, metadata = get_file_and_attr()
try:
# Do something with file
pd.read_csv(f, encoding="utf-8")
finally:
f.close()
每当文件对象通过某种管道传递或以给上下文管理器带来不便的顺序使用时,这样做都是合理的。至少在 cpython 中,99% 的时间文件在删除对象时关闭。
或者您可以编写自己的上下文管理器
import contextlib
@contextlib.contextmanager
def get_file_and_metadata():
metadata = {"foo": "bar"}
f = o.BytesIO()
f.write(b'content')
f.seek(0)
try:
yield f, metadata
finally:
f.close()
with get_file_and_attr() as f, metadata:
# Do something with file
pd.read_csv(f, encoding="utf-8")
根据您的评论,我意识到元数据可以直接放在 BytesIO 对象上,然后它的上下文管理器就可用了。
import io
def get_file_and_metadata():
metadata = {"foo": "bar"}
f = io.BytesIO()
f.write(b'content')
f.seek(0)
f.metadata = metadata
return f
with get_file_and_metadata() as f:
pd.read_csv(f, encoding="utf-8")
这三个内存或磁盘缓冲区遵循相同的访问模式。我要重点 BytesIO
.
如何传入文件或缓冲区对象供以后使用? 我在以下用例中遇到了很多麻烦:
def get_file_and_metadata():
metadata = {"foo": "bar"}
with io.BytesIO() as f:
f.write(b'content')
f.seek(0)
return f, metadata
f, metadata = get_file_and_metadata()
# Do something with file
pd.read_csv(f, encoding="utf-8")
我怀疑是因为 f.close()
在 return 语句之后是 运行。
with
关键字将在文件脱离上下文后自动关闭文件,即脱离 with 代码块(因此称为上下文管理器)。
相反,创建 file_obj 和 return。
def get_file_and_metadata():
metadata = {"foo": "bar"}
f = io.BytesIO()
f.write(b'content')
f.seek(0)
return f, metadata
f, metadata = get_file_and_metadata()
# Do something with file
print(f.read())
f.close()
del f # to remove it from memory.
with
套件终止时,close
是 运行。如果你想传回一个打开的 file-like 对象,你不应该在 with
中打开它。一种选择是完全放弃上下文管理器并将其留给调用者来清理对象。
def get_file_and_metadata():
metadata = {"foo": "bar"}
f = o.BytesIO()
f.write(b'content')
f.seek(0)
return f, metadata
f, metadata = get_file_and_attr()
try:
# Do something with file
pd.read_csv(f, encoding="utf-8")
finally:
f.close()
每当文件对象通过某种管道传递或以给上下文管理器带来不便的顺序使用时,这样做都是合理的。至少在 cpython 中,99% 的时间文件在删除对象时关闭。
或者您可以编写自己的上下文管理器
import contextlib
@contextlib.contextmanager
def get_file_and_metadata():
metadata = {"foo": "bar"}
f = o.BytesIO()
f.write(b'content')
f.seek(0)
try:
yield f, metadata
finally:
f.close()
with get_file_and_attr() as f, metadata:
# Do something with file
pd.read_csv(f, encoding="utf-8")
根据您的评论,我意识到元数据可以直接放在 BytesIO 对象上,然后它的上下文管理器就可用了。
import io
def get_file_and_metadata():
metadata = {"foo": "bar"}
f = io.BytesIO()
f.write(b'content')
f.seek(0)
f.metadata = metadata
return f
with get_file_and_metadata() as f:
pd.read_csv(f, encoding="utf-8")