How to check if variable is in workspace?

279 次查看(过去 30 天)
Hello, I want to check if a variable is in workspace and use it, instead of load my data from the slower HDD. So what I do is:
if exist('Nodes','var')==0
Nodes = csvread([path mesh], 0, 0);
assignin('base','Nodes',Nodes);
err = 'Test'
end
do something;
As far as I understand this should print
err =
Test
in the first run. In the second run it shouldn't. (I used the err = 'Test' to check if my Code runs correctly).
Somehow I do get in every single run the output
err =
Test
so I always reassign Nodes. What did I do wrong?
Any suggestions?
kind regards
  1 个评论
Stephen23
Stephen23 2017-12-7
编辑:Stephen23 2017-12-7
@Christian Berwanger: the line
exist('Nodes','var')==0
checks if Nodes exists in the workspace where that code is run. The line
assignin('base','Nodes',Nodes);
defines a variable called Nodes in the base workspace. There are two likely scenarios:
1. your code is in a function: then each time the function is called Nodes will be undefined in the function workspace and so the file will be loaded again.
2. you are running that code in a script called from the base workspace: then assignin is totally superfluous.
So both of these scenarios are flawed.
You could resolve the first scenario by using evalin. But I would suggest that this approach is flawed as well: it will work, but it is the kind of approach that beginners use to write slow, complex, inefficient code. Beginners love spamming all of their variables into the base workspace, and get some feeling of security from looking at all of those lovely variables sitting in the Variable Viewer pane. I know, I can remember that feeling!
But relying on the base workspace is a bad way to write code. Spamming variables into the base workspace is slow and is risky (e.g. overwriting variables without warning). Those beginners also typically try to write functions that magically access the variables in the base workspace (as you are trying to do) and perform some operations on them, but all of the techniques that can achieve this are slow, complex, inefficient, and will increase the chance of bugs. For example, introspective coding (e.g. exist) is slower than simply checking for an empty array or using nargin. On top of that, calling exist in different workspace is slower still, because any magical jumping between workspace will slow your code down (conversion to string, removes JIT code acceleration, etc).
Basically your entire approach forces you to write slow, complex, inefficient code.
If you want to write simpler, neater, efficient MATLAB code then forget about magically running things in other workspaces and magically checking if something exists somewhere else or not. Also, forget about the base workspace. Simply write functions, and pass all values as input and output arguments. Checking those arguments is easy. It will also be very efficient. This is the first step to learning how to write simple, reliable code. Functions are how experienced users write reliable, efficient, testable, robust code.
See my answer for a simpler, neater, more efficient solution.
PS: you might like to read this:

请先登录,再进行评论。

采纳的回答

Stephen23
Stephen23 2017-12-7
编辑:Stephen23 2017-12-7
Based on my comment to your question: a much better approach is to use persistent inside a function:
function out = myfun(inp)
% myfun is simple.
persistent mat
if isempty(mat)
mat = csvread('mydatafile.csv');
end
% do something with |mat|:
out = mat.*inp;
end
When the function is first called mat will be empty and it will load the data file. After that it will use the data stored using persistent.
Did you see what I did there? I turned your complex and buggy code into a simple solution using standard efficient MATLAB commands. No magical jumping between workspaces, inefficient string evaluation or slow introspective programming is required.
  4 个评论
Christian Berwanger
Oh. yeah. Sorry. in your Code it is mat. how can I remove mat, so next run will reinitialize it?
Stephen23
Stephen23 2017-12-7
编辑:Stephen23 2017-12-7
@Christian Berwanger: you can either add a flag as an input argument, and use that to reload the file, something like this:
function out = myfun(inp,flag)
% myfun is simple.
persistent mat
if isempty(mat) || (nargin>1&&flag)
mat = csvread('mydatafile.csv');
end
% do something with |mat|:
out = mat.*inp;
end
Or you can clear the function:
clear myfun

请先登录,再进行评论。

更多回答(1 个)

KL
KL 2017-12-7
编辑:KL 2017-12-7
You're probably using this code inside a function but not the main script that uses your base workspace. That explains why you use the ugly assignin.
Don't do this. Use your functions' parameters in a better way.
If you want to load Nodes only if it'S not in the base workspace, then
%main script
chk = exist('Nodes','var');
if ~chk
Nodes = getNodes(path,mesh,0,0);
disp('Node is loaded')
else
disp('Node is already loaded')
end
and your getNodes should look like,
function Nodes = getNodes(path,mesh,a,b)
Nodes = csvread([path mesh], a, b); %maybe fullfile(path,mesh)?
end
Now there's absolutely no need for assignin.
  1 个评论
Christian Berwanger
I am using Matlab as a Script for a Simulation tool. My tool opens an instance of Matlab and call the function with given parameters. So: My simulation tool knows the location of the Matlab function and call it with function(x,y,z).
As Matlab deletes every variable after a function is running I need to do that assignin to keep it in the workspace. I do not have any main Script.

请先登录,再进行评论。

类别

Help CenterFile Exchange 中查找有关 Data Type Identification 的更多信息

标签

产品

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!

Translated by