【问题标题】:will with statement close the file properly?with 语句会正确关闭文件吗?
【发布时间】:2023-03-16 02:23:01
【问题描述】:

我是 python 新手,对打开文件操作感到困惑。谁能帮我理解这个概念?谢谢

我在 source_file 类中打开一个文件:

class source_file:
    def close_file(self):
        self.source_file.close()

    define use_file(self):
        
        self.source_file = open(self.file_path, "r", encoding='gbk', errors='ignore')
        with self.source_file as lines:
            do_something()
        print(self.source_file)
        self.close_file()
        print(self.source_file)
        self.source_file.close()
        print(self.source_file)

当我运行这个 source_file.use_file()

它显示:

<_io.textiowrapper name="C:\\Temp\\law_dev\\source\source_file.txt" mode="r" encoding="gbk">

<_io.textiowrapper name="C:\\Temp\\law_dev\\source\source_file.txt" mode="r" encoding="gbk">

<_io.textiowrapper name="C:\\Temp\\law_dev\\source\source_file.txt" mode="r" encoding="gbk">

当我使用“with”语句时,我感到困惑,它应该关闭文件。或者当我使用函数 close_file 时,它​​应该关闭文件。或者当我使用 self.source_file.close() 时,它应该关闭文件。

但从打印上看,他们似乎都没有真正关闭文件。我仍然可以看到这个文件句柄。 是否正确关闭?

【问题讨论】:

  • 你在混合一堆语法。您只需要:with open(filepath) as file

标签: python file


【解决方案1】:

您已将文件句柄绑定到类,因此它还没有离开作用域,这就是您仍然可以看到它的原因。但是,您可以使用文件句柄上的closed 属性检查它是否已关闭。举个例子:

class X:
    def __init__(self, path):
        self.path = path

    def do_thing(self):
        with open(self.path) as fh:
            # This line is unnecessary, but shows what you are doing
            self.fh = fh
            print(f"Is closed in with? {fh.closed}")

        print(f"Is closed? {fh.closed}")


x = X('somefile.txt')

# Run function, context manager closes file handle
x.do_thing()
Is closed in with? False
Is closed? True

# Can still access file-handle since it's been bound to the instance
x.fh
<_io.TextIOWrapper name='somefile.txt' mode='r' encoding='UTF-8'>
x.fh.closed
True

真的,您可以跳过执行self.fh = fh 的步骤,只需让上下文管理器完成它的工作。此外,如果您所做的只是希望该类可以帮助您关闭文件,那么您可以将其简化为一个函数:

def do_thing(path):
    with open(path) as fh:
        # do things with fh
        print(f"I can access fh: {not fh.closed}")

    print(f"And now we're done: {fh.closed}")


do_thing('somefile.txt')
I can access fh: True
And now we're done: True

【讨论】:

  • 我正在做的是自动生成合同。我打算使用具有多种功能的类。每个函数都会产生一定的条件。所以我把打开的文件放到了self.source_file中。以便不同的功能可以将其用作通用句柄。我担心使用硬编码方式来传递文件路径。你有更好的做法吗?
  • 我认为您需要进一步充实您的示例。充其量只是表面上的理解,我会说如果你要重新使用它来编写,给类一个文件句柄可能会更糟。那时,我会做两件事之一:打开以追加并重新使用您给它的文件路径,或者给它一个缓冲的 io 对象,如 StringIO,您可以将内容写入其中。然后,您最后将 StringIO 读入目标文件
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2022-06-13
  • 1970-01-01
  • 2015-12-31
  • 1970-01-01
  • 2017-01-31
  • 1970-01-01
  • 2019-08-15
相关资源
最近更新 更多