Torna indietro   Hardware Upgrade Forum > Software > Programmazione

FRITZ!Repeater 1700 estende la rete super-veloce Wi-Fi 7
FRITZ!Repeater 1700 estende la rete super-veloce Wi-Fi 7
FRITZ!Repeater 1700 porta il Wi-Fi 7 dual-band nelle case connesse. Mette a disposizione fino a 2.880 Mbit/s su 5 GHz e 688 Mbit/s su 2,4 GHz, integrazione Mesh immediata via WPS con FRITZ!Box e funzioni smart come MLO per bassa latenza. Compatto, plug-and-play e pronto per il futuro, è la soluzione ideale per chi vuole coprire ogni angolo senza cavi o complicazioni
Fondazione Chips-IT, l'Italia alla riscossa nei chip. Il piano e la partnership EssilorLuxottica
Fondazione Chips-IT, l'Italia alla riscossa nei chip. Il piano e la partnership EssilorLuxottica
La Fondazione Chips-IT ha presentato a Pavia il piano strategico 2026-2028 per rafforzare l'ecosistema italiano dei semiconduttori. Con un focus su ricerca, design, talenti e infrastrutture, la Fondazione punta a consolidare il ruolo dell'Italia nel Chips Act europeo, sostenendo innovazione, collaborazione industriale e sovranità tecnologica.
Nutanix: innovazione, semplicità e IA al centro della strategia hybrid multicloud
Nutanix: innovazione, semplicità e IA al centro della strategia hybrid multicloud
Al Museo Alfa Romeo di Arese, Nutanix ha riunito clienti, partner ed esperti per .Next On Tour Italia e per mostrare come l’infrastruttura hybrid multicloud possa diventare il fondamento dell’innovazione, con una piattaforma capace di unificare applicazioni tradizionali, moderne architetture cloud-native e nuovi scenari basati sull’intelligenza artificiale
Tutti gli articoli Tutte le news

Vai al Forum
Rispondi
 
Strumenti
Old 23-02-2009, 16:07   #1
mad_hhatter
Senior Member
 
L'Avatar di mad_hhatter
 
Iscritto dal: Oct 2006
Messaggi: 1105
[Python] duck typing e semantica

ciao a tutti, volevo intavolare una discussione su un aspetto di Python che ancora non ho ben metabolizzato: la mancanza dell'overloading dei metodi.

Dato che in Python un metodo è identificato univocamente dal suo nome (all'interno di un dato namespace), non è consentito l'overloading dello stesso.

Poco male, visto che Python si affida al duck typing. Ma sorgono comuqnue due ordini di problemi.

Il primo problema nasce quando il duck typing non può funzionare perché oggetti di tipo diverso espongono una stessa funzioalità tramite metodi aventi nomi differenti.

In tal caso ho due strade:
1. verificare il tipo del parametro
2. verificare quale metodo viene esposto dal parametro

Il primo approccio ha il difetto di obbligare il programmatore a elencare esplicitamente TUTTI i tipi che il metodo dovrà supportare.

Il secondo approccio è un'estensione del concetto di duck typing e, in quanto tale, credo sia preferibile, ma apre la strada al secondo problema a cui accennavo poco fa: cosa succede quando due oggetti diversi possiedono metodi con lo stesso nome e diverse liste di parametri?

Ad esempio, un oggetto QuerySet in Django è simile a un oggetto di tipo list, ma mentre QuerySet ha un metodo count() che restituisce il numero di elementi nel QuerySet, il metodo count di list necessita di un parametro e restituisce il numero di volte in cui tale parametro compare nella lista.

In un caso del genere, la semplice verifica della presenza del metodo count non può funzionare.


Veniamo alle domande:
1. esiste un approccio che permetta di gestire entrambe le situazioni senza dover cambiare idioma?

2. è stato introdotto in python 3.0 un metodo per gestire queste situazioni? (mi pare ne avesse accennato raymond hettinger alla PyCon2 italia, forse le annotation?)
mad_hhatter è offline   Rispondi citando il messaggio o parte di esso
Old 23-02-2009, 17:02   #2
cdimauro
Senior Member
 
L'Avatar di cdimauro
 
Iscritto dal: Jan 2002
Città: Germania
Messaggi: 26110
Quote:
Originariamente inviato da mad_hhatter Guarda i messaggi
ciao a tutti, volevo intavolare una discussione su un aspetto di Python che ancora non ho ben metabolizzato: la mancanza dell'overloading dei metodi.

Dato che in Python un metodo è identificato univocamente dal suo nome (all'interno di un dato namespace), non è consentito l'overloading dello stesso.

Poco male, visto che Python si affida al duck typing. Ma sorgono comuqnue due ordini di problemi.

Il primo problema nasce quando il duck typing non può funzionare perché oggetti di tipo diverso espongono una stessa funzioalità tramite metodi aventi nomi differenti.
Se gli oggetti hanno metodi diversi, c'è poco da fare. Al limite puoi creare un metodo di una classe con lo stesso nome di quello usato nell'altra, rimappandolo se l'interfaccia è diversa, oppure riciclando direttamente quello col nome diverso che espone la medesima funzionalità.
Quote:
In tal caso ho due strade:
1. verificare il tipo del parametro
2. verificare quale metodo viene esposto dal parametro

Il primo approccio ha il difetto di obbligare il programmatore a elencare esplicitamente TUTTI i tipi che il metodo dovrà supportare.

Il secondo approccio è un'estensione del concetto di duck typing e, in quanto tale, credo sia preferibile, ma apre la strada al secondo problema a cui accennavo poco fa: cosa succede quando due oggetti diversi possiedono metodi con lo stesso nome e diverse liste di parametri?

Ad esempio, un oggetto QuerySet in Django è simile a un oggetto di tipo list, ma mentre QuerySet ha un metodo count() che restituisce il numero di elementi nel QuerySet, il metodo count di list necessita di un parametro e restituisce il numero di volte in cui tale parametro compare nella lista.

In un caso del genere, la semplice verifica della presenza del metodo count non può funzionare.

Veniamo alle domande:
1. esiste un approccio che permetta di gestire entrambe le situazioni senza dover cambiare idioma?
Se i metodi si chiamano allo stesso modo, ma hanno parametri e/o funzionamento diversi, non si possono conciliare le due cose.

Al limite potresti estendere uno dei due oggetti in modo da sovrascrivere il metodo count di uno e farlo funzionare esattamente come l'altro. Ma in questo modo se passi l'oggetto a una funzione che si aspetta il count originale, non funzionerebbe più nulla.

La soluzione è di avere un'interfaccia comune che implementano entrambe le classi, e personalmente mi affiderei alla funzione built-in len(), che già funziona con le liste restituendo il numero di elementi che contiene.

Estenderei poi QuerySet in questo modo:
Codice:
class MyQuerySet(QuerySet):
  def __len__(self):

    return QuerySet.count(self)
Oppure:
Codice:
class MyQuerySet(QuerySet):

  __len__ = QuerySet.count
Visto che __len__ e count hanno esattamente la stessa interfaccia (non hanno nessun parametro, a parte self, e restituiscono un valore numerico che è proprio ciò che si vuole).

A questo punto utilizzerei len() per entrambi i tipi di oggetto.
Quote:
2. è stato introdotto in python 3.0 un metodo per gestire queste situazioni? (mi pare ne avesse accennato raymond hettinger alla PyCon2 italia, forse le annotation?)
Le annotation servono soltanto per annotare, appunto, informazioni sui parametri di una funzione (o metodo) e/o sul valore restituito. Ma sono a puro scopo informativo: Python non le usa per determinare il tipo di oggetto passato a una funzione, perché ciò avviene sempre e comunque in maniera dinamica, a runtime e al momento preciso in cui viene poi usato l'oggetto passato come parametro.

Tutto ciò ovviamente se ho capito cosa intendevi.

Se ti servono altre informazioni, chiedi pure.
__________________
Per iniziare a programmare c'è solo Python con questo o quest'altro (più avanzato) libro
@LinkedIn Non parlo in alcun modo a nome dell'azienda per la quale lavoro
Ho poco tempo per frequentare il forum; eventualmente, contattatemi in PVT o nel mio sito. Fanboys
cdimauro è offline   Rispondi citando il messaggio o parte di esso
Old 23-02-2009, 17:42   #3
mad_hhatter
Senior Member
 
L'Avatar di mad_hhatter
 
Iscritto dal: Oct 2006
Messaggi: 1105
ciao cesare, grazie per le risposte.

Avevo già preso in considerazione le tue soluzioni, il problema è che a volte sono decisamente overkill rispetto al problema da risolvere. Inoltre nel cas di django il problema è che QuerySet non si crea esplicitamente ma viene restituito attraverso dei factory method quindi oltre a estendere QuerySet dovrei modificare il framework per restituire il nuovo tipo esteso...

Per le annotazioni, probabilmente avevo frainteso il discorso di Raymond.

Grazie per l'aiuto, prezioso come sempre
mad_hhatter è offline   Rispondi citando il messaggio o parte di esso
Old 23-02-2009, 22:13   #4
cdimauro
Senior Member
 
L'Avatar di cdimauro
 
Iscritto dal: Jan 2002
Città: Germania
Messaggi: 26110
Quote:
Originariamente inviato da mad_hhatter Guarda i messaggi
ciao cesare, grazie per le risposte.

Avevo già preso in considerazione le tue soluzioni, il problema è che a volte sono decisamente overkill rispetto al problema da risolvere. Inoltre nel cas di django il problema è che QuerySet non si crea esplicitamente ma viene restituito attraverso dei factory method quindi oltre a estendere QuerySet dovrei modificare il framework per restituire il nuovo tipo esteso...
Ah, ho capito. In questo caso le soluzioni che ti propongo sono due, e non necessitano di estendere nessuna classe, perché sfruttano appunto la dinamicità intrinseca di Python.

Soluzione 1. Supposto che la classe QuerySet si trovi nel modulo x.y.z:
Codice:
x.y.z.QuerySet.__len__ = x.y.z.QuerySet.count
da piazzare ovviamente dopo l'import di x.y.z e prima di utilizzare QuerySet.

Soluzione2. Supponiamo che foo() sia la funzione che torni un'istanza di QuerySet:
Codice:
Records = x.y.z.foo()
Records.__len__ = Records.count
Si tratta di due soluzioni simili, visto che sostanzialmente fanno la stessa cosa: aggiungere il metodo __len__.
Solo che la prima lo fa alla classe base, per cui una volta aggiunto ad essa verrà automaticamente ereditato da tutte le istanze di QuerySet, incluse quelle già create.
La seconda soluzione invece lo aggiunge soltanto all'istanza appena creata.

Una parziale riscrittura della seconda soluzione potrebbe essere questa:
Codice:
def DecoratedQS(Instance):
  Instance.__len__ = Instance.count
  return Instance

Records = DecoratedQS(x.y.z.foo())
O, meglio ancora, creando una funzione foo "locale" che esegue il wrapping di quella che usi nel modulo x.y.z:
Codice:
def foo():
  Instance = x.y.z.foo()
  Instance.__len__ = Instance.count
  return Instance

Records = foo()
Personalmente mi piace di più quest'ultima, perché non "sporca" né la classe QuerySet, che mantiene la propria identità, né allunga la stesura del codice dovendo passare l'istanza creata a una funzione per poi finalmente poterla utilizzare.
Quote:
Per le annotazioni, probabilmente avevo frainteso il discorso di Raymond.
Può essere, perché sono soltanto elementi decorativi.

Per curiosità: ma hai sentito Raymond alla scorsa PyCon2, oppure da qualche altra parte?
Quote:
Grazie per l'aiuto, prezioso come sempre
Figurati. E' un piacere cercare di essere utile, nei limiti del tempo che ho a disposizione.

Come vedi soluzioni ai problemi ne esistono diverse (probabilmente ce ne saranno altre). La cosa bella che trovo in Python è che grazie alla sua dinamicità è possibile crearne di utili e interessanti che con altri linguaggi nemmeno mi sarei sognato di fare, in quanto non possibili o estremamente macchinosi. Il tutto mantenendo il codice sempre pulito ed elegante.

Per lo meno, questa è l'impressione che ho dopo un po' di anni che ci lavoro.
__________________
Per iniziare a programmare c'è solo Python con questo o quest'altro (più avanzato) libro
@LinkedIn Non parlo in alcun modo a nome dell'azienda per la quale lavoro
Ho poco tempo per frequentare il forum; eventualmente, contattatemi in PVT o nel mio sito. Fanboys
cdimauro è offline   Rispondi citando il messaggio o parte di esso
Old 23-02-2009, 23:01   #5
mad_hhatter
Senior Member
 
L'Avatar di mad_hhatter
 
Iscritto dal: Oct 2006
Messaggi: 1105
mmm... queste ultime soluzioni mi piacciono particolarmente: sono concise e molto chiare. Grazie molte!

Si, ho sentito Raymond alla PyCon2, ma all'epoca della conferenza avevo alle spalle solo una settimana di python per cui molto probabilmente ho frainteso alcuni discorsi su python 3.0

Da allora python è il linguaggio che uso ogni giorno al lavoro (devo ringraziare il mio capo e un collega per questo ) e non smetto di rendermi conto di quanto sia divertente e stimolante, soprattutto non smette di sorprendermi con soluzioni impensabili con altri linguaggi. A volte mi rendo conto che è necessario spogliarsi di alcuni costrutti acquisiti essendo cresciuto con Java all'università per poter apprezzare appieno python.
mad_hhatter è offline   Rispondi citando il messaggio o parte di esso
Old 23-02-2009, 23:07   #6
cdimauro
Senior Member
 
L'Avatar di cdimauro
 
Iscritto dal: Jan 2002
Città: Germania
Messaggi: 26110
E' esattamente lo stesso motivo che mi ha portato a "innamorarmi" di Python, che ormai uso quasi esclusivamente per lavorare. Con lui ho ritrovato il piacere di programmare in maniera "creativa".

Comunque alla PyCon2 c'ero pure io, ed ero quello che ha sparato a Raymond le ultime tre domande di fila e a cui volevano strappare via il microfono.
__________________
Per iniziare a programmare c'è solo Python con questo o quest'altro (più avanzato) libro
@LinkedIn Non parlo in alcun modo a nome dell'azienda per la quale lavoro
Ho poco tempo per frequentare il forum; eventualmente, contattatemi in PVT o nel mio sito. Fanboys
cdimauro è offline   Rispondi citando il messaggio o parte di esso
Old 24-02-2009, 10:12   #7
mad_hhatter
Senior Member
 
L'Avatar di mad_hhatter
 
Iscritto dal: Oct 2006
Messaggi: 1105
Quote:
Originariamente inviato da cdimauro Guarda i messaggi
E' esattamente lo stesso motivo che mi ha portato a "innamorarmi" di Python, che ormai uso quasi esclusivamente per lavorare. Con lui ho ritrovato il piacere di programmare in maniera "creativa".

Comunque alla PyCon2 c'ero pure io, ed ero quello che ha sparato a Raymond le ultime tre domande di fila e a cui volevano strappare via il microfono.
purtroppo non ricordo, ma magari ci vedremo a maggio a PyCon 3
mad_hhatter è offline   Rispondi citando il messaggio o parte di esso
 Rispondi


FRITZ!Repeater 1700 estende la rete super-veloce Wi-Fi 7 FRITZ!Repeater 1700 estende la rete super-veloce...
Fondazione Chips-IT, l'Italia alla riscossa nei chip. Il piano e la partnership EssilorLuxottica Fondazione Chips-IT, l'Italia alla riscossa nei ...
Nutanix: innovazione, semplicità e IA al centro della strategia hybrid multicloud Nutanix: innovazione, semplicità e IA al ...
Lenovo LOQ 15i Gen 10 (15IRX10) alla prova: il notebook gaming 'budget' che non ti aspetti Lenovo LOQ 15i Gen 10 (15IRX10) alla prova: il n...
Due mesi di Battlefield 6: dalla campagna al battle royale, è l'FPS che stavamo aspettando Due mesi di Battlefield 6: dalla campagna al bat...
'Thank You', l'update gratuito per tutti...
L'IA è più brava degli uma...
Tutti i vincitori dei The Game Awards 20...
Instagram sta usando l'IA per migliorare...
Super prezzo per iPhone 16e: il modello ...
HP LaserJet MFP M234sdw, in prova la mul...
Phantom Blade Zero ha finalmente una dat...
Google e Apple stanno collaborando per r...
180 Hz in 5K? Il nuovo monitor di ASUS m...
L'Europa salva le auto termiche? Forse s...
Total War: Warhammer 40K è realt&...
NVIDIA rassicura il mondo HPC: il format...
Lenny Kravitz diventa un villain in 007 ...
Saros rinviato ad aprile 2026: il nuovo ...
EPYC Embedded 2005: AMD punta su efficie...
Chromium
GPU-Z
OCCT
LibreOffice Portable
Opera One Portable
Opera One 106
CCleaner Portable
CCleaner Standard
Cpu-Z
Driver NVIDIA GeForce 546.65 WHQL
SmartFTP
Trillian
Google Chrome Portable
Google Chrome 120
VirtualBox
Tutti gli articoli Tutte le news Tutti i download

Strumenti

Regole
Non Puoi aprire nuove discussioni
Non Puoi rispondere ai messaggi
Non Puoi allegare file
Non Puoi modificare i tuoi messaggi

Il codice vB è On
Le Faccine sono On
Il codice [IMG] è On
Il codice HTML è Off
Vai al Forum


Tutti gli orari sono GMT +1. Ora sono le: 23:54.


Powered by vBulletin® Version 3.6.4
Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
Served by www3v