2016-05-23 50 views
5

Sono su MATLAB R2014b e ho una domanda che illustrerò con il seguente esempio.Perché è possibile importare un pacchetto * dopo * utilizzando il suo contenuto in una funzione?

MWE può essere eseguito nel modo seguente o download it as a .zip file here.

Creare una cartella del pacchetto +test sul vostro percorso con quattro file di funzioni in esso:

+test 
    a.m 
    b.m 
    c.m 
    d.m 

Contenuto a.m:

function a 
disp 'Hello World!' 

Contenuto b.m:

function b 
a 

Se eseguire b dal co mm e linea, dovrai prima importare il pacchetto test (import test.*) o eseguire test.b.

L'esecuzione di b causerà un errore, poiché l'ambito della funzione b non contiene la funzione a. Dobbiamo importarlo prima che possa essere usato. Per questo ho creato c.m:

function c 
import test.* 
a 

Ora esecuzione c funziona bene.

Ora la mia domanda. Se cambio c.m a (salvato in d.m):

function d 
a 
import test.* 

Vale a dire il comando di importazione viene emesso dopo la chiamata alla funzione pacchetto a. L'esecuzione di d funziona comunque correttamente, come se la posizione del comando di importazione in d.m non fosse importante. Sembra che l'importazione si sia verificata prima che la chiamata funzioni a, che in d.m si verifica sulla riga prima dell'importazione.

Perché ciò accade. È questo il comportamento previsto e quali sono i suoi usi? Come e in quale ordine MATLAB legge un file .m e lo elabora? E più fuori tema, ma in generale: in che modo l'importazione dei pacchetti viene gestita in lingue diverse rispetto a MATLAB, l'ordine dei comandi è importante?

La mia conclusione preventiva basata sui commenti: Probabilmente è consigliabile utilizzare la funzione di importazione all'inizio o vicino al codice MATLAB. Ciò rende chiaramente visibile il contenuto importato disponibile nell'intero elemento (ad esempio la funzione). Inoltre impedisce l'assunzione errata che prima dell'importazione il contenuto non sia ancora disponibile o si riferisca a una cosa diversa con lo stesso nome.

+0

@thewaywewalk Sono sicuro che non è il mio malinteso. Sono stato molto attento con i pacchetti importati prima di modificare 'b.m'. Ho usato 'clear all',' clear classes' e 'clear import' prima di ogni passo che ho fatto, ma a giudicare dalla documentazione su' import', questo non è necessario: ogni funzione ha il proprio spazio di lavoro e lista di importazione (puoi controllare questo con 'L = import'). Anche se lo spazio di lavoro principale di MATLAB ha un pacchetto importato, non verrà passato a nessuna funzione chiamata dalla riga di comando. Nota: gli script funzionano nello spazio di lavoro in cui sono chiamati, quindi ereditano la lista di importazione da lì. – Erik

+0

Ho modificato la domanda. Ora 'b.m' non è cambiato, sono stati aggiunti invece due file' c.m' e 'd.m'. Ho anche aggiunto il MWE come file .zip per coloro che vogliono provarlo da soli. La funzione 'd.m' ora è quella con il comportamento interessante. – Erik

+2

Capisco il tuo problema ora. Non ho una risposta, però, ma il comando di importazione sembra essere pre-elaborato prima che venga chiamato qualsiasi altro. Il documento dice *** Non utilizzare l'importazione in istruzioni condizionali all'interno di una funzione. MATLAB sottopone a pre-elaborazione l'istruzione import prima di valutare le variabili nelle istruzioni condizionali. ***. – thewaywewalk

risposta

3

MATLAB esegue analisi del codice statico prima di valutare una funzione per determinare le variabili/funzioni utilizzate da tale funzione. La valutazione delle istruzioni import fa parte di questa analisi del codice statico. Questo è di progettazione perché se si usa un pacchetto e si usano le sue funzioni, MATLAB deve saperlo durante l'analisi del codice statico. Di conseguenza, a prescindere da in cui inserisci l'istruzione import all'interno della tua funzione, avrà lo stesso effetto che avrebbe se fosse all'inizio della funzione.

È possibile eseguire facilmente il test osservando l'uscita di import che elencherà tutti i pacchetti importati correnti.

+test/a.m

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

test.a() 

% test.* 

Questo è il motivo per cui the documentation states-non pose import dichiarazione all'interno di un condizionale.

Non utilizzare import in istruzioni condizionali all'interno di una funzione. MATLAB sottopone a pre-elaborazione l'istruzione import prima di valutare le variabili nelle istruzioni condizionali.

function a(x) 
    disp(import) 
    if x 
     import test.* 
    else 
     import othertest.* 
    end 
end 

test.a() 

% test.* 
% othertest.* 

L'unico modo per evitare questo problema è quello di consentire l'analizzatore di codice statico per determinare (senza dubbio) che non viene eseguita un'istruzione import. Possiamo farlo facendo in modo che la nostra dichiarazione condizionale sia semplicemente un valore logico.

function a() 
    disp(import) 
    if true 
     import test.* 
    else 
     import othertest.* 
    end 
end 

test.a() 

% test.* 

Per quanto riguarda l'importazione rispetto ad altre lingue, dipende molto dalla lingua. Ad esempio, in Python, è necessario inserire importprima di per accedere ai contenuti del modulo. Nella mia esperienza, questo è il caso tipico, ma sono sicuro che ci sono molte eccezioni. Ogni lingua sarà diversa.

+1

Solo per aggiungere che in Java normalmente si aggiungono le importazioni all'inizio di ogni file. Tuttavia, Java non è esattamente come Matlab. in C++ la parola chiave 'using' fa la stessa cosa, e viene normalmente aggiunta all'inizio di ogni file (dopo il ** # include ** s). Tread molto attentamente quando si utilizzano queste importazioni. Nel caso ci siano più funzioni con lo stesso nome. In tal caso è meglio usare la notazione a punti. Vorrei raccomandare di usare l'importazione all'inizio di ogni ambito e solo importare funzioni uniche. – patrik