Matlab中的上下文管理器:在Matlab中调用__enter__

时间:2017-11-09 01:22:37

标签: python matlab exit enter contextmanager

我有一个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

1 个答案:

答案 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__方法是否可能被隐式调用,但我还没有确定它。