Riprendiamo i concetti della programmazione ad Oggetti:

In python tutto e' oggetto!

(classe, funzione, metodo, attributo, numero, stringa, ecc)
Ogni oggetto appartiene ad un qualche tipo.
Ogni oggetto e' accessibile per un nome

Oggetto
Un oggetto ha due parti fondamentali
 - Attributi
    sono variabili che contengono i dati
 - Metodi
    sono funzioni con accesso implicito all'oggetto stesso
     e quindi anche ai suoi attributi

Classe
Una classe definisce una struttura
    formata da Attributi e Metodi
 e permette di creare oggetti (istanziare) con la struttura definita

In gergo si dice che gli oggetti
 - appartengono a quella classe
    o
 - sono istanze di quella classe.

Gli oggetti di una stessa classe condividono:
    - i metodi
    - la lista degli attributi

 ma i valori degli attributi (dati) sono distiniti per ogni oggetto

Ereditarieta'
Le classi costituiscono una gerarchia
 in quanto e' possibile derivare (ereditare) una classe da un'altra.
In questo caso la classe da cui si deriva prende il sopranome di
 - superclasse (classe base)

Percio' un oggetto non ha solo i metodi e gli attributi della propria
 classe ma anche tutti quelli delle classi da cui deriva!

Si parla di eredita' multipla quando una classe deriva da piu' classi.
 In altre parole a piu' classi base.

Polimorfismo
L'esecuzione di un metodo (con lo stesso nome)
 su oggetti diversi produce effetti diversi.

Esempio classico una classe 'Geometria' ha un metodo per il calcolo 'Area'
 che opera in modo distinto a seconda dell'oggetto di appartenenza
 (Cercio, Quadratro, Rombo, ecc)

In molti linguaggi questo e' legato al fatto che derivino tutti
 dalla stessa superclasse, In python e' diverso perche' usa le interfaccie!!!

Override
Una sottoClasse puo' fornire una implementazione diversa del proprio metodo
 rispetto a quella definita nella superClasse.
Comunque preserva l'accesso all'implementazione originale!

Metodi Virtuali
Una classe puo' dichiare un metodo senza fornire l'implementazione
 quest'ultima e' demandata alle sottoClassi.
Questo e' proprio il caso del metodo che calcola l'area nella
 classe 'Geometria' che demanda alle sottoClassi l'implementazione
 del calcolo non potendo conoscere a priori le caratteristiche.

In questo caso il metodo virtuale viene sovrascritto nella sottoClasse
 (es: Cerchio) implementendo un 'Override' per specificare il proprio
  metodo di calcolo dell'area.
Allo stesso tempo cosi' facendo implementiamo quello che si chiama
 'Polomorfismo'.

Binding
La relazione tra nome ed un oggetto viene chiamata 'Binding'
 la si realizza con una assegnazione

La funzione id() ritorna l'identificativo univoco di un oggetto
>>> id(1)
>>> 123457

# assegnazione (bindig tra 'a' e '1')
>>> a = 1
# l'identificativo e' lo stesso!!!
>>> id(a)
>>> 123457

Mapping
E' la mappatura della relazione tra nome(chiave) e oggetto(valore)
 implementata di solito attraverso un dizionario.

Namespace
Sono un insieme di nomi relativi ad un ambito

es: locals
    insieme di tutti nomi locali
es: globals
    insieme di tutti nomi globali
es: built-in
    insieme di tutti i nomi interni

non esiste alcuna relazione tra nomi uguali in namespace diversi!!!

Scope
Lo scope di una variabile e' la parte di testo
 visibile direttamente senza qualificarla

es: in un modulo 'pippo' ho definito un funzione 'pluto'
     questo sara' visibile a tutte le funzioni del modulo stesso
    ma se volessi accedere alla stessa funziona a partire da un'altro
     modulo dovrei qualificarla usando il nome 'pippo.pluto'

Search
Gli scope sono determinati staticamente ma vengono usati dinamicamente.
 In altre parole la ricerca del nome avviene cercando in vari scope
  contenuti uno dentro l'altro.

In python la sequenza di ricerca avviene per LGB
    prima si guarda in Locals, poi in Globals ed infine in Built-in

Il built-in viene costruito alla partenza dell'interprete e non viene
 piu' modificato!!!

La parola chiave 'global' permette di forzare il riferimento sia di
 lettura che di scrittura allo scope Globals.

es: se assegnamo ad una variabile 'x' il valore '2' x=2
     questa se non esiste in locals viene automaticamente creata ed inserita
    se prefissiamo con la parola chiave 'global x' forziamo l'interprete
     a non usare lo scope locals per la variabile 'x' e ricercarla in globals

Moduli
A cosa servono:
 - Riutilizzo del codice
 - Condividere strutture ed oggetti
 - Servono a suddividere lo spazio dei Nomi
 - Organizzare le funzionalita'

Corrispondono:
 alle librerie degli altri linguaggi

Cosa sono:
 sono dei file di testo che contengono codice python
 o delle librerie scritte in C condivise.

Metaclasse
il tipo a cui appartiene una classe e' detto in modo
    improprio:
 metaclasse di quella classe.
    corretto:
 metaclasse delle _istanze_ di quella classe

il rapporto che esiste tra:
    metaclasse e classe
e' lo stesso che esiste tra:
    istanza e la classe (o tipo) di quella istanza

la metaclasse ti serve se devi personalizzare il comportamento di
    alcune classi
--- COSI' COME ----
la classe ti serve se devi personalizzare il comportamento di
    alcune istanze

normalmente si eredita da type e si fa un 'Override' di
    __call__
 per definire cosa succede alle chiamate della classe, e/o di
    __new__
 per definire cosa succede durante la costruzione di nuove classi di quella
  metaclasse.

Singleton
Una classe tale che, quando la chiami, invece di farti
 una nuova istanza ogni volta fa sempre la stessa

Borg
Classi tali che tutte le loro istanze condividono lo stesso stato
 con una metaclasse che garantisce l' astrazione sollevando un'eccezione
 se mai viene istanziata una classe che abbia alcuni metodi  astratti
 che non siano stati sottoposti ad override.
e-mail _orciml_@gmail.com eliminare gli underscore per ottenere l'indirizzo corretto!!!