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

Why can you import a package *after* using its content in a function?

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

MWE可以按如下方式制作或download it as a .zip file here.

在您的路径上创建一个包文件夹 +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

现在 运行ning c 工作正常。

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

function d
a
import test.*

即在 调用包函数 a 之后 发出导入命令。 运行 d 仍然可以正常工作,就好像 d.m 中导入命令的位置无关紧要一样。导入似乎发生在调用函数 a 之前,在 d.m 中发生在导入之前的行上。

为什么会这样。这是预期的行为吗?它的用途是什么? MATLAB 如何以及以什么顺序读取 .m 文件并处理它?还有更多题外话,但总的来说:与 MATLAB 相比,如何用不同的语言处理导入包,命令的顺序重要吗?

我根据评论得出的先发制人的结论:最好的做法可能是只在 MATLAB 代码的开头或附近使用导入函数。这使得导入的内容在整个元素(例如函数)中都可用,清晰可见。它还可以防止错误的假设,即在导入之前,内容尚不可用或引用具有相同名称的不同事物。

MATLAB 在计算函数之前执行静态代码分析以确定该函数使用的 variables/functions。 import 语句的评估是此静态代码分析的一部分。这是设计使然,因为如果您 import 一个包然后使用它的函数,MATLAB 需要在静态代码分析期间知道这一点。因此,无论 在哪里 你把 import 语句放在你的函数中,它的效果就好像它在函数的开头一样。

您可以通过查看 importoutput 轻松测试它,它将列出所有当前导入的包。

+test/a.m

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

test.a()

%   test.*

这就是为什么 the documentation states 而不是 import 语句放在条件语句中的原因。

Do not use import in conditional statements inside a function. MATLAB preprocesses the import statement before evaluating the variables in the conditional statements.

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 。根据我的经验,这是典型案例,但我敢肯定也有很多例外。每种语言都会有所不同。