【问题标题】:Is self-reference possible in MATLAB?在 MATLAB 中是否可以进行自引用?
【发布时间】:2011-04-12 14:37:35
【问题描述】:

here 所述,包中的函数以及类中的静态方法仍然需要使用 packagename.functionname 语法或 import packagename.* 用于 each 函数(因为导入是一部分函数工作区而不是全局的)。这意味着稍后更改包/类名称可能会变得乏味。

有什么方法可以做类似import this.* 的事情,即一个包/类名不可知的方法来访问同一个包/类中的所有函数/静态方法?

【问题讨论】:

  • 我很想听听这个问题的答案...
  • @Andrey 我也是。也许赏金会帮助找到一些巧妙的方法...计算时间
  • 如果我们对此给予足够多的支持,也许他们会将其添加到 R2012a 中?
  • @Andrew 当然,试一试;-) 在那之前,我猜这里的“正确”答案只是“不,但如果你真的需要它,请使用this HackGnovice
  • @AndrewJanke ...还是 R2019a? ??????

标签: matlab packages self-reference


【解决方案1】:

所以...这不需要 importthis 也被导入吗?还是 importthis 是您一直在使用的功能?

在每个函数的顶部粘贴一个带有 this 的“import this”块似乎并不复杂,然后您不必担心 importthis 会在您的路径中。我倾向于觉得依赖路径是危险的。

“导入此”块

%% Import own package
[~, pkgdir] = fileparts(fileparts(mfilename('fullpath')));
import([pkgdir(2:end) '.*']);

您甚至可以将它放在 try/catch 块中,以确保它在包目录中,如果不是,则决定如何处理。

%% Import own package
try
    [~, pkgdir] = fileparts(fileparts(mfilename('fullpath'))); 
    import([pkgdir(2:end)'.*']);
catch err
    if ~strcmp(err.identifier,'MATLAB:UndefinedFunction'), rethrow(err); end
end

【讨论】:

  • 对于嵌套包甚至是这样的:mfiledir = fileparts(mfilename); pkg_pos = strfind(mfiledir, [filesep '+']); if ~isempty(pkg_pos), import([strrep(mfiledir((pkg_pos(1)+2):end), [filesep '+'], '.') '.*']); end
【解决方案2】:

我最近遇到了类似的问题,并找到了以下软件包的解决方案。但是它非常hacky。

您使用可选参数创建一个名为 import this 的函数。

function to_eval = importthis(exclude_list)
if nargin == 0
    exclude_list = [];
end
var_name = genvarname('A', exclude_list); %avoid shadowing
to_eval = ['[~,'...
    , var_name...
    , ']=fileparts(fileparts(mfilename(''fullpath'')));'... %get containing dir
    , 'eval([''import '','...
    , var_name...
    , '(2:end),''.*'']);'... %remove '+'
    , 'clear '... %clean up
    , var_name
    ];
end

这个函数返回一个字符串,然后可以是evaled 导入“this”包。因此,在您的包函数中,您可以将以下内容放在顶部附近:

function B = myfunc(A)
eval(importthis);
%function body
end

您也可以将who 传递给importhis,保持函数的命名空间干净。

function B = myfunc(A)
eval(importthis(who));
%function body
end

我无法决定我应该为自己的所作所为感到自豪还是受到质疑。

【讨论】:

  • 干得好!我猜如果你使用evalin('caller',...),你可以保存外部eval 并直接调用importthis。这也是对How to convert a directory into a package?的回答
  • 我试过evalin,但它似乎不起作用。也可以在没有eval 的情况下获取包|目录名称。您可以抛出一个虚拟异常,捕获它并检查它,因为它包含堆栈跟踪。或者你可以滥用dbstack。除此之外,我的解决方案与您链接的解决方案相同。
【解决方案3】:

这可能不是一个值得赏金的答案,但由于您没有任何答案,我想我还是会发布它!您可以通过只需要定义一次的类的实例来调用静态方法。您可以通过函数句柄调用函数,但这需要每个函数一个句柄。

使用这些技术,您可以在一处定义所有静态方法和函数引用。然后,您将在整个包中使用这些引用。然后,如果您决定稍后更改包名称,您只需要更新这些都存储在一个地方的引用。

见:

Calling Static Methods

您还可以使用类的实例调用静态方法, 像任何方法一样:

obj = MyClass;

值 = obj.pi(.001);

function_handle (@)

以下示例为驼峰函数创建函数句柄 并将其分配给变量 fhandle。

fhandle = @humps;

【讨论】:

  • 好吧,如果让赏金白白浪费掉,那就太可惜了:-7 但你的答案可能是目前最接近的答案,所以感谢您发布它
猜你喜欢
  • 2017-07-06
  • 2011-03-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-02-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多