python - 在 init 中使用 contextmanager
问题描述
在下面的代码中,我不明白为什么with super().__init__(*args, **kwargs):
MyFileIO2 中的行会抛出有关丢失的错误,__exit__
而 MyFileIO 类的一切工作都很好。我真的不明白在 init 内部或外部进行操作有什么区别。有人可以告诉我这里发生了什么吗?
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__
实际上并没有返回任何内容。
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__
所发生的是正在通过上下文管理器传递的返回值,因此您有效地拥有了这个:
with None:
pass
AttributeError: __enter__
上下文管理器尝试调用对象__enter__
上的方法NoneType
,但这是一个无效的操作。
推荐阅读
- java - 忽略警告的后果是什么:java中未经检查的转换
- dynamic - 调用 COBOL 程序的默认模式是什么?静态还是动态?
- python - 将数据框的列值聚合到新的数据框
- c# - 在可预测的错误发生之前停止循环
- r - R中主成分分析中的内积
- reactjs - HOC 传递属性
- c# - Xamarin Android SpeechRecognizer - SpeechRecognizerError.Network
- google-analytics - 在 Google Analytics(分析)仪表板上检查事件参数
- javascript - 在虚拟表中单击功能不起作用
- spring-security - 使用 mfa 重置密码的 JWT