【问题标题】:Why can you import a package *after* using its content in a function?为什么你可以在函数中使用它的内容 *after* 导入一个包?
【发布时间】:2016-09-20 02:00:53
【问题描述】:

我在使用 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

现在运行 c 工作正常。

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

function d
a
import test.*

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

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

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

【问题讨论】:

  • @thewaywewalk 我确定这不是我的误解。在编辑b.m 之前,我对导入的包非常小心。在我采取任何步骤之前,我使用了clear allclear classesclear import,但是从import 上的文档来看,这不是必需的:每个函数都有自己的工作区和导入列表(你可以用@检查这个987654352@)。即使主 MATLAB 工作区已导入包,它也不会传递给您从命令行调用的任何函数。注意:脚本在调用它们的工作区中工作,因此它们从那里继承导入列表。
  • 我已经编辑了这个问题。现在b.m 没有更改,而是添加了两个文件c.md.m。我还为那些想自己尝试的人添加了 MWE 作为 .zip 文件。函数d.m 现在是具有有趣行为的函数。
  • 我现在明白你的问题了。虽然我没有答案,但导入命令似乎在调用其他任何内容之前已经过预处理。文档说 不要在函数内的条件语句中使用 import。 MATLAB 在计算条件语句中的变量之前预处理 import 语句。.
  • @thewaywewalk 我认为这应该是一个答案。
  • @Bernhard 答案有点弱。

标签: matlab import package packages


【解决方案1】:

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

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

+test/a.m

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

test.a()

%   test.*

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

不要在函数内的条件语句中使用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。以我的经验,这是典型的案例,但我相信也有很多例外。每种语言都会有所不同。

【讨论】:

  • 只是为了在Java中添加它,您通常在每个文件的开头添加导入。 Java 并不完全像 Matlab。在 c++ 中,关键字 using 做同样的事情,通常添加在每个文件的开头(在 #includes 之后)。使用这些进口产品时要非常小心。如果有多个具有相同名称的函数。在这种情况下,最好使用点符号。我建议在每个作用域的开头使用 import 并且只导入唯一的函数。
猜你喜欢
  • 2012-10-19
  • 1970-01-01
  • 1970-01-01
  • 2023-01-01
  • 2021-10-10
  • 1970-01-01
  • 2020-11-01
  • 2017-05-20
  • 2010-09-11
相关资源
最近更新 更多