为什么可以在函数中使用包的内容在*之后导入包



我在MATLAB R2014b上,有一个问题,我将用下面的例子来说明。

MWE可以如下制作,也可以在此处以.zip文件的形式下载。

在您的路径上创建一个包文件夹+test,其中包含四个功能文件:

+test
a.m
b.m
c.m
d.m

a.m:的内容

function a
disp 'Hello World!'

b.m:的内容

function b
a

如果从命令行运行b,则必须首先导入test包(import test.*)或运行test.b

运行b将导致错误,因为函数b的作用域不包含函数a。我们必须进口它才能使用。为此,我创建了c.m:

function c
import test.*
a

现在运行c运行正常。

现在是我的问题。如果我将c.m更改为(保存在d.m中):

function d
a
import test.*

也就是说,import命令是在调用包函数a之后发出的。运行d仍然很好,就好像导入命令在d.m中的位置无关紧要一样。导入似乎发生在调用函数a之前,在d.m中,调用发生在导入之前的行上。

为什么会发生这种情况。这是预期行为吗?它的用途是什么?MATLAB是如何读取.m文件并对其进行处理的?更偏离主题,但总的来说:与MATLAB相比,如何用不同的语言处理导入包,命令的顺序重要吗?

我根据评论得出的结论是:最好的做法是只在MATLAB代码开始时或接近开始时使用导入函数。这使得导入的内容在整个元素(例如函数)中都是可用的。它还防止了错误的假设,即在导入之前,内容还不可用或引用了具有相同名称的不同内容。

MATLAB在评估函数之前执行静态代码分析,以确定该函数使用的变量/函数。import语句的评估是此静态代码分析的一部分。这是经过设计的,因为如果你import一个包,然后使用它的函数,MATLAB需要在静态代码分析过程中知道这一点。因此,无论import语句放在函数中的何处,它都将具有与函数开头相同的效果。

您可以通过查看import输出来轻松测试这一点,该输出将列出所有当前导入的包。

+test/a.m

function a(x)
disp(import)
import test.*
end
test.a()
%   test.*

这就是为什么文档states tonotimport语句放入条件中的原因。

不要在函数内的条件语句中使用import。MATLAB在评估条件语句中的变量之前对import语句进行预处理。

function a(x)
disp(import)
if x
import test.*
else
import othertest.*
end
end
test.a()
%   test.*
%   othertest.*

避免这种行为的唯一方法是允许静态代码分析器确定(毫无疑问)不会执行import语句。我们可以通过将条件语句简单地作为一个逻辑值来实现这一点。

function a()
disp(import)
if true
import test.*
else
import othertest.*
end
end
test.a()
%   test.*

就进口而言,与其他语言相比,这实际上取决于语言。例如,在Python中,必须将import放在访问模块内容之前。根据我的经验,这是典型的情况,但我相信也有很多例外。每种语言都会有所不同。