如何使用Python关闭上下文管理器

7 投票
1 回答
5448 浏览
提问于 2025-04-17 05:58

标准库里的 open 函数可以作为一个普通的函数使用:

f = open('file.txt')
print(type(f))
<type 'file'>

也可以作为一个上下文管理器使用:

with open('file.txt') as f:
    print(type(f))
<type 'file'>

我想用 contextlib.closing 来模仿这种行为,其中 File 是我自己定义的文件输入输出类:

def my_open(filename):
    f = File(filename)
    f.open()
    return closing(f)

作为上下文管理器使用时,这个效果是正常的:

with my_open('file.txt') as f:
    print(type(f))
<class '__main__.File'>

但如果我直接调用它,就会返回一个 closing 对象,而不是我的对象:

f = my_open(filename)
print(type(f))
<class 'contextlib.closing'>

那么,我该如何实现 my_open,使它既能作为上下文管理器使用,又能在直接调用时返回我的 File 对象呢?

完整的示例可以在 GitHub 上找到: https://gist.github.com/1352573

1 个回答

13

最简单的方法可能就是自己实现 __enter____exit__ 这两个方法。像下面这样就可以了:

class File(object):
   # ... all the methods you already have ...

   # context management
   def __enter__(self):
       return self

   def __exit__(self, *exc_info):
       self.close()

顺便说一下,把你的 open 方法的工作放在 __init__ 方法里会更符合常规写法。

撰写回答