在 init 中使用 contextmanager
Use contextmanager inside init
在下面的代码中,我不明白为什么 MyFileIO2 中的 with super().__init__(*args, **kwargs):
行会抛出有关缺少 __exit__
的错误,而 MyFileIO class 一切正常。我真的不明白在 init 内部或外部执行 with 之间到底有什么区别。有人能告诉我这是怎么回事吗?
import io
class MyFileIO(io.FileIO):
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
def __enter__(self, *args, **kwargs):
f = super().__enter__(*args, **kwargs)
print('first byte of file: ', f.read(1))
return f
class MyFileIO2(io.FileIO):
def __enter__(self, *args, **kwargs):
f = super().__enter__(*args, **kwargs)
print('first byte of file: ', f.read(1))
return f
def __init__(self, *args, **kwargs):
with super().__init__(*args, **kwargs): # AttributeError: __exit__
pass
path = 'some_file.bin'
with MyFileIO(path, 'rb'):
pass
MyFileIO2(path, 'rb')
您需要在 self
上调用上下文管理器,因为 __init__
实际上 return 什么都没有。
class MyFileIO2(io.FileIO):
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
with self:
pass
def __enter__(self, *args, **kwargs):
f = super().__enter__(*args, **kwargs)
print('First byte of file: ', f.read(1))
return f
为了测试,我创建了一个包含内容 "hello world".
的二进制文件
_ = MyFileIO2(path, 'rb')
# First byte of file: b'h'
发生的事情是 super().__init__
的 return 值正在通过上下文管理器传递,因此您实际上拥有:
with None:
pass
AttributeError: __enter__
上下文管理器尝试在 NoneType
对象上调用 __enter__
方法,但这是一个无效操作。
在下面的代码中,我不明白为什么 MyFileIO2 中的 with super().__init__(*args, **kwargs):
行会抛出有关缺少 __exit__
的错误,而 MyFileIO class 一切正常。我真的不明白在 init 内部或外部执行 with 之间到底有什么区别。有人能告诉我这是怎么回事吗?
import io
class MyFileIO(io.FileIO):
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
def __enter__(self, *args, **kwargs):
f = super().__enter__(*args, **kwargs)
print('first byte of file: ', f.read(1))
return f
class MyFileIO2(io.FileIO):
def __enter__(self, *args, **kwargs):
f = super().__enter__(*args, **kwargs)
print('first byte of file: ', f.read(1))
return f
def __init__(self, *args, **kwargs):
with super().__init__(*args, **kwargs): # AttributeError: __exit__
pass
path = 'some_file.bin'
with MyFileIO(path, 'rb'):
pass
MyFileIO2(path, 'rb')
您需要在 self
上调用上下文管理器,因为 __init__
实际上 return 什么都没有。
class MyFileIO2(io.FileIO):
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
with self:
pass
def __enter__(self, *args, **kwargs):
f = super().__enter__(*args, **kwargs)
print('First byte of file: ', f.read(1))
return f
为了测试,我创建了一个包含内容 "hello world".
的二进制文件_ = MyFileIO2(path, 'rb')
# First byte of file: b'h'
发生的事情是 super().__init__
的 return 值正在通过上下文管理器传递,因此您实际上拥有:
with None:
pass
AttributeError: __enter__
上下文管理器尝试在 NoneType
对象上调用 __enter__
方法,但这是一个无效操作。