[Python] With... as... per sopprimere NameError

Pietro Battiston me a pietrobattiston.it
Mar 14 Maggio 2013 17:24:47 CEST


Il giorno mar, 14/05/2013 alle 16.49 +0200, Manlio Perillo ha scritto:
> Il 14/05/2013 16:37, Pietro Battiston ha scritto:
> > [...]
> >>
> >> Cosa usano: Common Lisp?
> > 
> > No, cose come R, STATA, Gretl (o meglio Hansl, il suo linguaggio di
> > programmazione)... linguaggi che vanno (alcuni più, altri meno) bene per
> > l'analisi statistica, e con cui poi impazzisci quando cerchi di fare
> > qualsiasi altra cosa (discorso leggermente meno vero per R).
> > 
> > [...]
> > 
> >> Common Lisp con la macro with-slots di CLOS è l'unica soluzione più
> >> espressiva che mi viene in mente, per quello che vuoi fare.
> > 
> > Potrei sbagliarmi, ma mi pare che "exec()" in Python 3 faccia
> > esattamente tutto ciò...
> > 
> 
> No, è molto diverso.
> 
> Con Common Lisp puoi modificare il comportamento del linguaggio a
> compile time, così come con Python lo puoi fare a run time.
> 
> Nel tuo caso, il problema è che in Python la gestione delle variabili
> locali di una funzione viene "decisa" a compile time, e quindi non puoi
> fare quello che vuoi.
> 

Sì, OK, l'ho fatta _molto_ semplice. Intendevo che a costo di infilare
un "eval()" in ogni funzione, ci siamo...


> > [...]
> >> Quello che vuoi fare credo non sia possibile in Python, e francamente
> >> non vedo in che modo aumenti l'espressività..
> >>
> > 
> > Ignoro se ci sia una definizione univoca di espressività, quindi non
> > sono certo di quale sia la tua risposta al tuo dubbio. Di certo
> > ridurrerebbe enormemente la quantità di codice che è necessario scrivere
> > per fare una qualsiasi analisi econometrica (se guardo quella che sto
> > facendo ora, credo che sarebbe di un fattore 2, per non parlare della
> > maggiore semplicità di manutenzione).
> > 
> 
> Sicuramente la differenza tra:
> 
>    d.x + d.y
> e
> 
>    x + y
> 
> è che la seconda è più corta, però:
> 
>  1) Non ci sono differenze nello sforzo da fare nella manutenzione


OK, "manutenzione" non era la parola giusta, intendevo più
"leggibilità" (che chiaramente influisce sulla manutenzione). E in
realtà non finisce qui: è frequentissimo anche scrivere

d["x"][condizione] + d["y"][condizione]

("condizione" è a sua volta un oggetto pandas, qualcosa come "d.year >
1985"), che può sì diventare

d.x[condizione] + d.y[condizione]

ma è comunque molto peggio di

with d.context( condizione ):
    x + y

soprattutto quando poi hai varie condizioni binarie da combinare...

E sì, certo che puoi fare

cond = condizione
d.x[cond] = d.y[cond]

... ma insomma, credo di avere dato un'idea di quanto si allunga e si
complica il codice. Se vuoi un real world example, questa è "una" riga
vera del mio codice attuale:

dff["rat"][cond] = ( dff["mysignal"][cond] + dff["guessA_l2"][cond] +
dff["guessD_l2"][cond] + (2 * dff["guessA_l1"][cond] -
dff["guessC_l2"][cond]) ) / 4

che con il tuo consiglio diventa:

dff.rat[cond] = ( dff.mysignal[cond] + dff.guessA_l2[cond] +
dff.guessD_l2[cond] + (2 * dff.guessA_l1[cond] - dff.guessC_l2[cond])
) / 4

e che in gretl è esattamente

smpl --restrict cond
rat = (mysignal + guessA_l2 + guessD_l2+(2 * guessA_l1 - guessC_l2)) / 4

e nei miei sogni pythoneschi sarebbe:

with dff.context( cond ):
    rat = (mysignal+guessA_l2+guessD_l2 + (2*guessA_l1 - guessC_l2) )/ 4


Moltiplica per tante volte (per le quali basterebbe un unico "with"). Ti
assicuro che mi sono bastati due giorni di tentativi per rendermi conto
che se non raggiungo qualcosa di simile, non posso pensare di usare
Python per l'econometria.


>  2) La prima è piu esplicita, perchè vedi subito a quale "namespace" x
>     ed y appartengono
> 

Ma sì, sono d'accordo, io vorrei solo poter raggruppare l'esplicitezza
in una riga di codice (e sarebbe l'indentazione a ricordarmi che ho
qualcosa in sospeso...)

> 
> Nota che non ci sono problemi a fare in modo da avere
> 
>   d.x + d.y
> 
> invece di
> 
>   d["x"] + d["y"]
> 
> se d è un dizionario.
> 

Questo in realtà in pandas c'è già (e confesso che mi sento stupido per
lo scarso uso che ne ho fatto finora)... ma non mi basta (e se non basta
a me che in Python vorrei friggerci anche le uova, vuol dire che non
potrò mai cercare di convincere un collega che non sa cosa sia!)

ciao

Pietro



Maggiori informazioni sulla lista Python