[Python] Domande varie
Daniele Varrazzo
piro a develer.com
Lun 20 Ott 2008 16:47:11 CEST
On Mon, 20 Oct 2008 16:19:20 +0200, "Antonello Mangone"
<antonello.mangone a gmail.com> wrote:
> Gli attributi indicano che stai passando un parametro di tipo tupla
Veramente no: come dizionario. "Come tupla" è con un solo asterisco. Provo
a spiegare meglio a Valerio...
> Il giorno 20 ottobre 2008 15.53, Valerio Pachera <sirio81 a gmail.com> ha
> scritto:
>
>> Ciao ragazzi, sto leggendo del codice di alcuni programmi e vi sono
>> delle cose che non mi sono chiare.
>>
>> def __init__(self, **kw):
>> super(Document, self).__init__(**kw)
>>
>> Correggetemi se sbaglio:
>> Qua viene definito il costruttore che richiama il costruttore della
>> classe genitore per estenderlo.
>>
>> Cosa sono gli asterischi????
>> kv ha un significato particolare?
kw è solo un nome (sta per "keywords"), non ha un significato speciale.
Nel corpo del costruttore sarà un dizionario, dove le chiavi saranno i
nomi degli argomenti passati al costruttore, e i valori saranno i valori
degli argomenti. La sintassi non è legata ai soli costruttori, ma a tutte
le funzioni:
In [24]: def f(**kw): print kw
In [25]: f(a=10, b=20, c=30)
{'a': 10, 'c': 30, 'b': 20}
Solo i parametri nominali (passati alla funzione con un nome) vengono messi
nel dizionario delle keyword. Eventuali argomenti posizionali finiscono in
una tupla di argomenti, che può essere usata con la sintassi con un solo
asterisco, quello che intendeva Antonello.
In [26]: def g(*args, **kw): print args, kw
In [27]: g(10, 20, foo=30, bar=40)
(10, 20) {'foo': 30, 'bar': 40}
Tutto questo nella definizione degli argomenti di una funzione. La cosa
"duale" avviene al richiamo di una funzione: se passi una tupla con un
asterisco, questa viene "espansa" coprendo altrettanti argomenti
posizionali
In [28]: def h(a, b, c):
....: print a, b, c
In [29]: args = (10, 20, 30)
In [30]: h(*args)
10 20 30
mentre un dizionario con due asterischi viene espanso a coprire gli
argomenti nominali:
In [31]: kwargs = {'a': 11, 'b':12, 'c':13}
In [32]: h(**kwargs)
11 12 13
Il costruttore che hai postato come esempio mette insieme le due cose e fa
sì che, al momento di creare un'istanza della sottoclasse, tutti gli
argomenti passati al costruttore vengano trasmessi integralmente al
costruttore della classe di base. E' un pattern che si usa tutte le volte
che si vuole wrappare in modo generico una funzione. Per esempio se voglio
creare una funzione che logga tutti i richiami di altre funzioni:
In [35]: def call_with_log(f, *args, **kwargs):
....: print "calling", f, args, kwargs
....: return f(*args, **kwargs)
In [36]: def sum(a, b, carry=0):
return a+b+carry
In [38]: call_with_log(sum, 10, 20)
calling <function sum at 0xc9d578> (10, 20) {}
Out[38]: 30
In [39]: call_with_log(sum, 10, 20, carry=1)
calling <function sum at 0xc9d578> (10, 20) {'carry': 1}
Out[39]: 31
ho potuto scrivere questa funzione molto generica, in grado di funzionare
con qualunque funzione e qualunque combinazione di argomenti.
--
Daniele Varrazzo - Develer S.r.l.
http://www.develer.com
Maggiori informazioni sulla lista
Python