如何在Python中传递文件、BytesIO、StringIO以供以后使用?
这三个内存或磁盘缓冲区遵循相同的访问模式。我将聚焦于如何在Python中传递文件、BytesIO、StringIO以供以后使用?,python,io,Python,Io,这三个内存或磁盘缓冲区遵循相同的访问模式。我将聚焦于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 = ge
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代码块)后自动关闭文件(因此称为上下文管理器)
相反,创建一个文件并返回该文件
def get_file_和_metadata():
元数据={“foo”:“bar”}
f=io.BytesIO()
f、 写(b'content')
f、 搜索(0)
返回f,元数据
f、 元数据=获取文件和元数据()
#用文件做些什么
打印(f.read())
f、 关闭()
del f#将其从内存中删除。
with
关键字将在文件脱离上下文(即with代码块)后自动关闭文件(因此称为上下文管理器)
相反,创建一个文件并返回该文件
def get_file_和_metadata():
元数据={“foo”:“bar”}
f=io.BytesIO()
f、 写(b'content')
f、 搜索(0)
返回f,元数据
f、 元数据=获取文件和元数据()
#用文件做些什么
打印(f.read())
f、 关闭()
del f#将其从内存中删除。
close
在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()
当文件对象通过某种管道传递时,或者以使上下文管理器不方便的顺序使用时,这样做是合理的。当对象被删除时,99%的时间文件被关闭,至少在cpython中是这样
或者您可以编写自己的上下文管理器
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")
close
在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()
当文件对象通过某种管道传递时,或者以使上下文管理器不方便的顺序使用时,这样做是合理的。当对象被删除时,99%的时间文件被关闭,至少在cpython中是这样
或者您可以编写自己的上下文管理器
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")
正是我想要的谢谢!在您的上下文管理器的后续操作中,您是否可以不使用contextlib decorator或yield语法而仅使用带有get\u file\u和\u attr()的,元数据:
,而不使用contextlib decorator或yield语法?
的需要一个带有\uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu\uu
方法的对象contextlib.contextmanger
将生成器转换为上下文管理器(添加这些特殊方法)。因此,您可以将get\u file\u和\u attr
转到一个类,并添加这些方法或使用。只是意识到我做得不对。。。现在修复。谢谢,这证实了我的怀疑,因此我返回了一个元组。如果只返回了一个缓冲区或文件对象,那么您就不需要contextmanager语法(因为缓冲区/文件对象已经有\uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu
和\uuuuuuuuuuuuuuuuuu!在您的上下文管理器的后续操作中,您是否可以不使用contextlib decorator或yield语法而仅使用带有get\u file\u和\u attr()的,元数据:
,而不使用contextlib decorator或yield语法?
的需要一个带有\uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu\uu
方法的对象contextlib.contextmanger
将生成器转换为上下文管理器(添加这些特殊方法)。因此,您可以将get\u file\u和\u attr
转到一个类,并添加这些方法或使用。只是意识到我做得不对。。。现在修复。谢谢,这证实了我的怀疑,因此我返回了一个元组。如果只返回了缓冲区或文件对象,那么您就不需要contextmanager语法(因为缓冲区/文件对象已经有了\uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu。