[Python] Domanda "teorica"

Daniele Varrazzo piro a develer.com
Ven 1 Feb 2008 16:50:43 CET


Pietro Battiston ha scritto:
> Salve a tutti.
> 
> Ho una domanda un po' teorica, ma che in realtà viene da un problema
> concreto che ho usando il modulo dateutil.
> 
> Se io ho una funzione con dei parametri facoltativi di cui conosco il
> valore di default, sono certissimo che non passare alcun valore
> equivalga a passare il valore di default?
> Questo, è per una funzione in python (e per quel che ne so io), ovvio.
> Ma una funzione di libreria scritta in C ha modo di "sapere" se un dato
> parametro è stato passato oppure no?
> 
> In pratica, per la funzione dateutil.relativedelta.relativedelta, la cui
> documentazione dice:
> 
> dateutil.relativedelta.relativedelta(self, dt1=None, dt2=None, years=0,
> months=0, days=0, leapdays=0, weeks=0, hours=0, minutes=0, seconds=0,
> microseconds=0, year=None, month=None, day=None, weekday=None,
> yearday=None, nlyearday=None, hour=None, minute=None, second=None,
> microsecond=None)
> 
> , ho la certezza più assoluta che le seguenti due invocazioni siano a
> tutti gli effetti identiche?
> 
> dateutil.relativedelta.relativedelta(years=1)
> dateutil.relativedelta.relativedelta(None, None, 1)
> 
> Per rispondere a tale domanda ho letto anche un po' della documentazione
> su come estendere Python con il C, ma non posso dire di averne ricavata
> una certezza proprio assoluta...
> 
> 
> In alternativa, è possibile specificare in modo dinamico l'associazione
> "nome del parametro-valore passato"? Ad esempio, se ho un valore "val"
> da passare come parametro, esiste un modo di rendere il seguente
> (stupido) codice senza scrivere due volte l'invocazione della funzione
> relativedelta?
> 
> if val > 12:
>     risultato=relativedelta(years=val)
> else:
>     risultato=relativedelta(months=val)
> 
> (ovviamente faccio entrambe le domande perché nel mio caso ho un po' di
> "if" annidati e sono costretto a scrivere ben più di due volte tale
> invocazione...)

Ciao,

rispondo prima all'ultima domanda: secondo me ti può aiutare a non porti la 
prima domanda.

In Python puoi fare:

     params = {}

     if val > 12:
         params['years'] = val
     else:
         params['months'] = val

     risultato = relativedelta(**params)

quindi accumulare nella maniera più fantasiosa che preferisci named parameters 
  in un dizionario e poi espanderlo come parametri di una chiamata.

Riguardo la prima domanda, penso che

      dateutil.relativedelta.relativedelta(None, None, 1)

sia abbastanza garantito come funzionamento, ma trovandoti davanti un 
costruttore così complesso (21 parametri!) faresti meglio ad usare i named 
parameters:

     If you have a procedure with ten parameters, you probably missed some.
                                 -- Alan Perlis

...quindi stai sicuro che la prossima versione della libreria avrà 22 
parametri :) Affidarsi ai nomi anziché alle posizioni mi sembra più robusto.

Passando alla prima domanda, hai una *certezza molto ragionevole* che passare 
il default equivalga a non passare niente, ma c'è sempre l'incertezza di 
documentazione non ben aggiornata (anche perché con le estensioni C non si può 
fare introspezione con le signature). Mi sembra un'ipotesi remota comunque. 
Resta il fatto che gestirei questa chiamata usando solo named parameters.

Spero di esserti stato utile, ciao!


-- 
Daniele Varrazzo - Develer S.r.l.
http://www.develer.com


More information about the Python mailing list