2012-11-22 20 views
5

ho creare una funzionefunzione di MATLAB con argomento non richiesto

function y = getValue(modelName, param, option) 
    open_system(modelName); 
    runModel(option); 
    y = getActiveFun(param); 
end 

Vorrei quando si chiama questa funzione per avere la scelta di passare o meno argomento option da parte di alcuni altri file che io chiamo la funzione con tutti gli argomenti e a volte mi piacerebbe chiamarlo senza passare l'argomento option?

Vorrei chiamare: getValue(modelName, param) da altri file

Come potrei farlo?

+0

Cosa ti aspetteresti che 'runModel' faccia se non passi il parametro' option'? –

+0

Vorrei chiamare: getValue (modelName, param) da altri file – lola

risposta

7

Il modo più semplice per farlo è quello di utilizzare la variabile nargin:

function y = getValue(modelName,param,option) 
    open_system(modelName); 

    if (nargin < 3) 
     # No option passed, do something like 
     runModel('defaultOption') 
    else 
     # Option passed 
     runModel(option); 
    end 
    y = getActiveFun(param); 
end 

nargin è solo il numero di argomenti di input che sono stati effettivamente presentati. Pertanto, nargin == 3 indica che il parametro opzione è stato impostato, nargin < 3, che non è stato impostato.

Così, si potrebbe ora chiamare sempre la vostra funzione come

result = getValue('myModel', myParameter) 

o con tutti i parametri

result = getValue('myModel', myParameter, someOption) 
+0

Vorrei chiamare: getValue (modelName, param) da altri file (senza passare l'opzione alla funzione getValue – lola

+1

E questo è esattamente ciò che il codice sopra permette Se non si passa l'opzione, sarà necessario decidere come chiamare "runModel", quindi ho aggiunto un'opzione predefinita fittizia, ma è possibile gestirla come preferisci. – Thilo

1

Per completezza, vedere le nozioni di base (see documentation here).

In una funzione se non si utilizza un argomento, è solo un "avviso di programmazione", niente di più. Quindi il problema è che usi un parametro che può o non può essere fornito.

Quindi questo viene gestito utilizzando

nargin     % the number of parameters provided in current call 

nargin(function_name) % the number of parameters the declaration has 

Quindi, in base a questi è possibile programmare alcune condizioni e comprendono c'è il codice che utilizza i parametri di input non standard.

Per i casi più complessi varargin è più appropriato che gestisce l'elenco dei parametri di lunghezza variabile in cui l'ordine potrebbe non essere definito. Ma questo è troppo per questa domanda

2

Mentre le soluzioni con nargin sono già fornite e più o meno un uso standard all'interno della maggior parte delle basi di codici MATLAB, penso che ci sia un'alternativa migliore che sia più leggibile.

Con nargin in grandi funzioni, è necessario ricordare quale argomento 3 era esattamente. Soprattutto se si hanno più argomenti opzionali, diventa difficile tenere traccia o consentire che vengano passati alcuni argomenti facoltativi, mentre altri no.

Il primo e più semplice soluzione è la mia alternativa personale a nargin, e che sta usando la funzione exist:

function [output] = getValue(modelName,param,option, otherOption) 

if ~exist('option', 'var') || isempty(option) 
    option = 'defaultValueForOption'; 
end 

if ~exist('otherOption', 'var') || isempty(otherOption) 
    otherOption = 'defaultValueForOption'; 
end 

% perform other actions 

Il vantaggio è che ora tutto il codice di ingresso relativo è all'inizio ed è più verboso quanto a cosa dovrebbe accadere. Non ingombrerai il tuo altro codice con quella logica. Inoltre, è possibile integrare le istruzioni if con la convalida dell'input e tornare all'impostazione predefinita quando viene fornita un'opzione non valida.

L'altra possibilità è standard nelle versioni successive di MATLAB: la classe inputParser. Con questa classe, è possibile definire scenari ancora più complicati di parametri opzionali e persino coppie chiave-valore.

Di seguito è riportato un esempio auto-descrittivo che ho mantenuto per evitare di aver bisogno della documentazione ogni volta. Non

%% Usage Example input Parser 
% 
function output = FuncName(rParam1, rParam2, oParam1, oParam2, varargin) 

p = inputParser(); 

defaultValue = 0; 
validatorFunc = @(x)(true); % validator function should return true when x is valid 

%% Input Format definition 

p.addRequired('rParam1', validatorFunc); 
p.addRequired('rParam2', validatorFunc); 

p.addOptional('oParam1', defaultValue, validatorFunc); 
p.addOptional('oParam2', defaultValue, validatorFunc); 

p.addParamValue('kvParam1', defaultValue, validatorFunc); 
p.addParamValue('kvParam2', defaultValue, validatorFunc); 
p.addParamValue('kvParam3', defaultValue, validatorFunc); 
p.addParamValue('kvParam4', defaultValue, validatorFunc) 

%% Optional Settings 
% expand supplied struct to ParamValue pairs (or other arguments) 
p.StructExpand = true; % default: false 

%% Parse 
p.parse(rParam1, rParam2, oParam1, oParam2, varargin{:}) 

%% Retrieve results 
values = p.Results(); % structure with all values 
defaultedArgs = p.UsingDefaults; % cell array of all parameter names using defaults 
end 

Questo approccio è ancora più prolisso e personalmente, faccio piace molto il fatto che si deve ridefinire per ogni ingresso se è obbligatorio o facoltativo e che richiede un bel po 'di codice standard. Ma almeno, è una soluzione che è una soluzione standard e senza dubbio da preferire per le funzioni più grandi.

Entrambi gli approcci presentano uno svantaggio rispetto al metodo di controllo nargin: entrambi sono più lenti. Quindi, se si utilizzano queste funzioni in chiamate molto numerose (o si esegue solo un calcolo molto rapido), potrebbe essere più utile utilizzare nargin.

+0

Questo codice di esempio non funziona: ' p.expandStruct = true; 'dovrebbe essere' p.StructExpand = true; '. Fonte: [inputParser docs] (http://www.mathworks.com/help/matlab/ref/inputparser-class.html) –

+0

@BrandonJackson : grazie per avermi fatto sapere, ho adattato il mio esempio. – Egon

Problemi correlati