Получить дескриптор объекта с именем в виде строки (MATLAB) - PullRequest
0 голосов
/ 15 мая 2018

Учитывая имя переменной в виде строки (в моем случае это имя существующей переменной Simulink.Parameter в рабочей области, выбранной пользователем в качестве проектной переменной для оптимизации), я хотел бы иметь возможность доступа ксвойства объекта, такие как Simulink.Parameter.Min, Simulink.Parameter.Max, Simulink.Parameter.Value без использования eval () .До сих пор я использую (очень уродливое) решение

varnames = {'var1','var2'}; % Simulink.Parameter objects existing in workspace
objects = cell(length(varnames),1);
for i = 1:length(varnames)
    eval(['objects{i}=', varnames{i}, ';']) % Store objects in a cell array
end

В идеале это будет выглядеть следующим образом:

objects = get_object_handles_from_string(varnames);
value_1 = object{1}.Value(:);

В противном случае метод возвращает имя переменной с заданным дескриптором объекта.также было бы приемлемо.

Методы, которые, как я обнаружил, не работают, но могут быть полезны в противном случае:

  • whos находит имена и свойства переменных втекущее рабочее пространство, но без дескрипторов.
  • inputname возвращает имя переменной явного ввода функции в виде строки, но не работает для массивов ячеек объектов (см. этот вопрос ).
  • str2func возвращает дескриптор функции со строкой в ​​качестве ввода, но не разрешает доступ к атрибутам.
  • findobj возвращает объекты с массивом объектов для итерации, которых у меня нет.Может ли существовать метод, возвращающий все дескрипторы переменных рабочей области в виде массива?

Спасибо!

1 Ответ

0 голосов
/ 16 мая 2018

Это именно то, для чего eval.Да, вам следует избегать использования eval, но если вы хотите иметь тип пользователя в материале, который нужно оценить, вам нужно eval. или evalin, если вы хотите оценить его в базовом или рабочем пространстве вызывающего абонента , а не в текущем рабочем пространстве.

Не существует такой вещи, как "дескрипторы объектов" (кроме графических объектов, ноэто не то, о чем ты здесь говоришь).Есть переменные, владеющие массивами данных, вот и все.

Если вы не доверяете своим пользователям, не используйте eval.Они могут вводить что угодно, включая clear all или !\rm -rf /* (или любой другой эквивалент Windows для стирания диска).

В этом случае и при условии, что существует ограниченный набор переменных, которые пользователь можетуточните, сделайте

var1 = 1;
var2 = 2;
varnames = {'var1','var2'}; % Simulink.Parameter objects existing in workspace
objects = cell(size(varnames));
for i = 1:numel(varnames)
    objects{i} = get_variable_value(varnames{i}) % Store objects in a cell array
end

function val = get_variable_value(name)
   switch name
      case 'var1'
         val = evalin('caller',var1);
      case 'var2'
         val = evalin('caller',var2);
      otherwise
         error('Illegal variable name')
end
...