我有一个python包,我想在Matlab中使用它的类和方法。我知道这可以直接从Matlab 2014b开始。我的意思是你要做的就是在你的陈述开头添加py.
。到目前为止,这么好,我无法通过MATLAB找出如何处理上下文管理器,这些是使用with
语句调用的。例如,假设我们在名为app.py,
class App(object):
def __init__(self, input):
self._input = input
self._is_open = False
def __enter__(self):
self._is_open = True
# many other stuff going after this but not relevant to this problem
在Matlab中,我可以将其称为
app = py.app.App(input);
py.getattr(app, '_is_open')
ans =
logical
0
我在工作区中看到了App的实例。但是,正如预期的那样,只有__init__
以这种方式调用,而不是__enter__
。
那么,有没有办法从Matlab调用__enter__
,好像我们在Python中调用with App(input) as app:
一样?
注意:我使用的是Python 3.5.1和Matlab 2017b
答案 0 :(得分:1)
我不相信有任何方法可以从MATLAB调用Python类的__enter__
方法,但可以隐式调用__exit__
方法 (I'我将在下面进一步说明。)
首先考虑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__
方法是否可能被隐式调用,但我还没有确定它。