Matlab中的上下文管理器:在Matlab中调用__enter__ [英] Context Managers in Matlab: Invoking __enter__ in Matlab

查看:142
本文介绍了Matlab中的上下文管理器:在Matlab中调用__enter__的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个python包,我想在Matlab中使用它的类和方法.我知道自Matlab 2014b起可以直接完成此操作.我的意思是,您要做的就是在语句的开头添加py..但是到目前为止,到目前为止,我还无法弄清楚如何通过MATLAB处理上下文管理器,而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

解决方案

我不认为有任何方法可以从MATLAB调用Python类的__enter__方法,但是__exit__方法可能被隐式调用(我将在下面进一步解决).

首先考虑上下文管理器(通过__enter____exit__方法),这提供了一种以范围受限的方式分配和释放资源的方法,无论该范围是正常退出还是由于错误而退出. MATLAB的范围界定"方法较为有限:每个函数都有其自己的 onCleanup 对象来实现.当从内存中清除它们时,它们将调用给定的函数来管理现有资源. 示例将打开并从文件读取:

 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__(...)
 

它会找到一些帮助文本.它不是特别有用,但在那里.但是,当我创建一个对象并查看其方法列表时, __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__方法是否可能被隐式调用,但是我还没有确定.

I have a python package and I would like to use its classes and methods in Matlab. I know that this can be done directly since Matlab 2014b. I mean all you have to do is add py. in the beginning of your statements. So far so good, however, I couldn't figure out how to deal with context managers through MATLAB, which are invoked using the with statement. For instance, assume that we have the following class in a module called 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

In Matlab, I can call this as

app = py.app.App(input);
py.getattr(app, '_is_open')

ans =

logical

0

and I see an instance of App in my workspace. However, as expected only __init__ is invoked this way but not __enter__.

So, is there a way to invoke __enter__ from Matlab, as if we are calling it like with App(input) as app: in Python?

Note: I am using Python 3.5.1 and Matlab 2017b

解决方案

I don't believe there is any way to invoke the __enter__ method of a Python class from MATLAB, but the __exit__ method might be implicitly called (I'll address this further below).

It's important to first consider the purpose of context managers (via the __enter__ and __exit__ methods), which is to provide a way to allocate and release resources in a scope-limited fashion, whether or not that scope is exited normally or via an error. MATLAB has a more limited means of "scoping": each function has its own workspace, and control structures like loops, conditional statements, etc. within that function all share that workspace (unlike many languages in which these control structures have their own sub-scopes).

When a workspace is exited in MATLAB, the variables it contains are cleared, but any resources that were allocated may still need to be released. This can be achieved with onCleanup objects. When they are cleared from memory, they invoke a given function for managing existing resources. An example would be opening and reading from a file:

function openFileSafely(fileName)
  fid = fopen(fileName, 'r');
  c = onCleanup(@() fclose(fid));

  s = fread(fid);
  ...
end

Here, a file is opened and subsequently read from. An onCleanup object c is created that will close the file when c is cleared from memory upon exit from the function. If the file were simply closed with fclose(fid) at the end of the function, then an error exit from the function (such as during the course of reading data) would cause the file to still remain opened. Using an onCleanup object ensures that the file will be closed regardless of how the function exits. Here's an example of how this could be handled in Python:

with open('some_file', 'w') as opened_file:
    opened_file.write('Hola!')

Since MATLAB has a different means of "context management" than Python, this may explain why it's not possible to access the __enter__ method. I tried with a class I knew had one: the io.FileIO class. I first looked for help:

>> py.help('io.FileIO.__enter__')
Help on method_descriptor in io.FileIO:

io.FileIO.__enter__ = __enter__(...)

It finds some help text. It's not particularly helpful, but it's there. However, when I create an object and look at its methods list, neither __enter__ nor __exit__ (nor a clear equivalent) is there:

>> 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

I did notice something interesting when I cleared the fio object, though. While the fio object still existed (with the file open), I couldn't delete or move the file, as expected. However, after issuing the command clear fio, without first closing the file, I was able to interact with the file normally. This implies that the file was automatically closed. This makes me wonder if the __exit__ method might be getting implicitly invoked, but I have yet to determine it for certain.

这篇关于Matlab中的上下文管理器:在Matlab中调用__enter__的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆