2011-01-20 9 views
8

Ho scritto C# e il mantra che arriva dall'alto sembra "non usare mai la riflessione nel codice di produzione". L'ho usato per il codice di test, ma mai nulla che funzioni in natura. Tutti gli argomenti sembrano ragionevoli, e c'è sempre un modo per farlo aggiungendo un altro strato di astrazione o modello di progettazione o qualsiasi altra cosa.Non utilizzare mai la riflessione nel codice di produzione! Che mi dici di Python?

Ora sto iniziando a scrivere un codice Python serio, mi chiedo se valga lo stesso principio. Sembra che Python sia progettato pensando alla riflessione. Moduli e classi memorizzano membri in un dizionario facilmente accessibile. Le classi Meta dei modelli di Django, ad esempio, prendono le stringhe come membri di riferimento.

Potrei scrivere C#/Java in Python ma davvero non voglio. Credo ancora fermamente in "nessuna riflessione" per le suddette lingue. Il modo Python è fondamentalmente diverso?

+1

Questo è divertente, perché Reflection è così pesantemente utilizzato in entrambe le librerie .NET e di terze parti, che "non usando la riflessione" significherebbe "non usare .NET stesso". – Euphoric

+0

Sì, .NET usa la riflessione per fare ogni genere di cose. Ma un altro dei principi era "affidarsi a .NET e ad altre biblioteche per fare ciò che promettono". Che va bene se ci si attiene a librerie ben testate. Dovremmo preoccuparci principalmente dei bug nel nostro codice. – Joe

+0

Penso che si possa dire di qualsiasi tecnologia, non solo di Reflection. Finché sai cosa stai facendo e conosci i suoi alti e bassi, non trovo un motivo per non usarlo. – Euphoric

risposta

17

Come linguaggio dinamico Python è fondamentalmente diverso rispetto alle lingue tipizzate staticamente, quindi tutto è riflesso in esso :-) Anche non utilizzare mai il reflection nel codice di produzione (per le lingue statiche) sembra un po 'estremo per me.

+4

concordato. Dicendo _never_ di usare qualcosa e invece perdere tempo, il codice di debug/re-structuring invece di usare built in-function mi sembra un po 'sciocco. Naturalmente, se possibile, è meglio evitare la riflessione, ma non sempre. – Rob

+0

So che questo è un vecchio commento ma sono d'accordo. Inoltre, non utilizzare mai la riflessione nel codice di produzione sensibile al fattore tempo è il nostro mantra. La riflessione in .net è molto lenta. – Justin

6

Penso che "nessun riflesso nel codice di produzione" non sia corretto in C#.
La riflessione spesso consente al programmatore di fare le cose altrimenti impossibili.
Direi "nessuna riflessione per i membri non pubblici nel codice di produzione" e "usa la riflessione con attenzione!" se non usato correttamente, potresti perdere prestazioni. Utilizzato correttamente potrebbe farti guadagnare prestazioni (basti pensare alla riflessione statica) Non utilizzare la riflessione per codice chiamato in modo massivo.
Python è invece un linguaggio dinamico. Tutti i concetti sono diversi. La normalità (e il modo corretto di farlo) sta usando le tecniche di cui stai parlando.

+0

Cosa intendi per "riflessione statica", nemeno? – Nickolodeon

+0

In un modo molto veloce per spiegarlo, è un modo per compilare le informazioni raccolte per riflessione. In questo modo paghi solo una volta il costo della riflessione e il risultato compilato è quasi veloce quanto il codice puramente compilato. – nemenos

0

IMO il motivo per cui evito di utilizzare il reflection nel codice di produzione è il fatto che la riflessione potrebbe rendere il codice più difficile da mantenere e eseguire il debug.

+0

Se è pieno di riflessi, certo. Per qualcosa come una fabbrica di oggetti o una mappa della struttura, non sono del tutto d'accordo. – Rob

+0

@Rob: questo è sicuro! – ykatchou

0

La riflessione è una tecnologia molto avanzata e potente. Ma è lento. È possibile utilizzare la riflessione, ma non troppo spesso. Quindi gli sviluppatori CLR hanno aggiunto un altro tipo interessante a .NET 4.0 - di tipo dinamico. Consiglio vivamente di fare riferimento ad alcuni documenti o libri per maggiori informazioni. F.e. CLR via C#.

dynamic a = SomeFooInterface.GetsomeObjectWithUnknownInterface(); 
// returns object, for example, from another assembly. or some unknown instance. 
// But you know that there is method int GetValue() inside. 
// So you can call this method without any casts! 
int myValue = a.GetValue(); 
// This method is much faster then reflection! 

CLR via C#:

Ci sono anche molte occasioni in cui un programma deve agire sulle informazioni che esso non conosce fino a quando è esecuzione. Sebbene sia possibile utilizzare type-safe linguaggi di programmazione (come C#) per interagire con queste informazioni, la sintassi tende ad essere goffo, specialmente dal momento che si tende a lavorare molto con corde, e la performance è ostacolata pure. Se si sta scrivendo un'applicazione C# pura, l'unica occasione per cui si ha a che fare con informazioni determinate in fase di esecuzione è quando si utilizza la riflessione (discussa in capitolo 23). Tuttavia, molti sviluppatori utilizzano anche C# per comunicare con i componenti che non sono implementati in C# . Alcuni di questi componenti potrebbero essere .lingue NET-dinamico come Python o Ruby, o oggetti COM che supportano l'interfaccia IDispatch (possibilmente implementate in C nativo o C++), o HTML Document Object Model (DOM) oggetti (implementato utilizzando varie lingue e tecnologie). La comunicazione con gli oggetti DOM HTML è particolarmente utile quando si crea un'applicazione Microsoft Silverlight . Per rendere più semplice per gli sviluppatori che utilizzano il riflesso o comunicare con altri componenti , il compilatore C# ti offre un modo per contrassegnare il tipo di un'espressione come dinamico. È anche possibile inserire il risultato di un'espressione in una variabile e è possibile contrassegnare il tipo di una variabile come dinamica. Questa dinamica/variabile dinamica può essere utilizzata per richiamare un membro come un campo, una proprietà/indicizzatore , un metodo, delegato, e operatori unari/binari/di conversione. Quando il codice richiama un membro utilizzando un'espressione dinamica/variabile, il compilatore genera un codice IL speciale che descrive l'operazione desiderata. Questo codice speciale è denominato il carico utile. In fase di runtime, il codice payload determina l'operazione esatta a eseguita in base al tipo effettivo di l'oggetto a cui fa riferimento l'espressione dinamica/variabile .

+0

Grazie per quello. Potresti aver appena detto "CLR via C# pagina X", ne ho una copia qui! Questa domanda, tuttavia, riguarda Python not C#. – Joe

+0

La citazione è per qualcuno che non può avere la copia. E tu hai scritto che puoi usare un'altra lingua, quindi ho deciso di consigliarti C# back :). –

+0

> // Questo metodo è molto più veloce della riflessione! Divertente, perché l'unico modo per eseguire codice come questo su un tipo statico è usare la riflessione. – Euphoric

2

Sì, in questo aspetto, Python sviluppo è fundametally diverso.

Reflection in C#/Java fa riferimento alla capacità del runtime di conoscere le informazioni sul codice in esecuzione e di prendere decisioni basate su tali informazioni.

Poiché Python utilizza tipizzazione dinamica, ogni scoperta tipo è delegato al runtime e non il tempo di compilazione, in modo sostanzialmente che significa, che qualsiasi programma Python deve utilizzare riflessione per lavorare, solo che è non chiama riflettente, è chiamato in esecuzione il programma :)
Inoltre, la filosofia di Python abbraccia la natura dinamica dell'esecuzione, quindi non si dovrebbe esitare ad usarlo a proprio vantaggio.

P.S. Mentre si dovrebbe evitare di usare la riflessione in cicli stretti, e si dovrebbe essere consapevoli che la riflessione è più lenta di uno o due ordini di grandezza, non si dovrebbe aver paura di usarla quando è lo strumento giusto per il lavoro.

+0

Bella risposta. Ma c'è una differenza tra dire "myobject.foo()' e 'x = getattr (myobject," foo "); x(); '. Anche se è solo cosmetico. Nel primo il 'foo()' è compilato staticamente. Nel secondo, la stringa potrebbe essere prodotta in qualsiasi numero di modi. – Joe

+1

Eh, patata/solanum tuberosum ... in python, niether è compilato staticamente, quindi sono più o meno equivalenti. – SWeko

Problemi correlati