我不相信有任何方法可以从 MATLAB 调用 Python 类的 __enter__ 方法,但 __exit__ 方法可能会被隐式调用(我将进一步解决这个问题下面)。
首先考虑context managers 的目的很重要(通过__enter__ 和__exit__ 方法),即提供一种以有限范围的方式分配和释放资源的方法,无论该范围与否正常退出或通过错误退出。 MATLAB 的“作用域”方式更为有限:每个函数都有自己的workspace,并且该函数内的循环、条件语句等控制结构都共享该工作区(与许多语言不同,这些控制结构有自己的子范围)。
当在 MATLAB 中退出工作区时,其中包含的变量会被清除,但任何已分配的资源可能仍需要释放。这可以通过onCleanup 对象来实现。当它们从内存中清除时,它们会调用一个给定的函数来管理现有资源。 example 将打开并读取文件:
function openFileSafely(fileName)
fid = fopen(fileName, 'r');
c = onCleanup(@() fclose(fid));
s = fread(fid);
...
end
在这里,打开一个文件并随后从中读取。将创建一个 onCleanup 对象 c,当退出函数时从内存中清除 c 时,该对象将关闭文件。如果文件只是在函数结束时用fclose(fid) 关闭,那么函数的错误退出(例如在读取数据的过程中)将导致文件仍然保持打开状态。使用onCleanup 对象可确保无论函数如何退出,文件都将被关闭。以下是如何在 Python 中处理此问题的示例:
with open('some_file', 'w') as opened_file:
opened_file.write('Hola!')
由于 MATLAB 的“上下文管理”方式与 Python 不同,这可以解释为什么无法访问 __enter__ 方法。我尝试了一个我知道有的课程:io.FileIO 课程。我首先寻求帮助:
>> py.help('io.FileIO.__enter__')
Help on method_descriptor in io.FileIO:
io.FileIO.__enter__ = __enter__(...)
它会找到一些帮助文本。它不是特别有帮助,但它就在那里。但是,当我创建一个对象并查看它的 methods list 时,__enter__ 和 __exit__(也没有明确的等价物)都不存在:
>> fio = py.io.FileIO('test.txt');
>> methods(fio)
Methods for class py._io.FileIO:
FileIO eq ge le read readinto seek truncate writelines
char fileno gt lt readable readline seekable writable
close flush isatty ne readall readlines tell write
Methods of py._io.FileIO inherited from handle.
Methods for class handle:
addlistener eq findprop gt le ne
delete findobj ge isvalid lt notify
不过,当我清除 fio 对象时,我确实注意到了一些有趣的事情。虽然fio 对象仍然存在(文件打开),但我无法按预期删除或移动文件。但是,在发出命令clear fio 之后,没有先关闭文件,我能够正常与文件交互。这意味着该文件已自动关闭。这让我想知道__exit__ 方法是否会被隐式调用,但我还没有确定它。