[Python] variabili globali e d'istanza: provengo da java

Lawrence Oluyede l.oluyede a gmail.com
Mer 26 Dic 2007 12:21:53 CET


On Dec 26, 2007 11:47 AM, ugaciaka <ugaciaka a gmail.com> wrote:
> Ho notato che in python c'è una cosa che, provenendo da java, mi
> provoca disorientamento.

Eh eh succede a tutti :D

> Le variabili!

Ottima affermazioni. Ti anticipo che in Python le variabili non sono
proprio variabili, ma etichette per un contenuto.
Il concetto che ha Java di variabile è un po' diverso, ma proseguiamo:

> Riassumendo: ho scritto un programmino (senza nessuna classe ma con
> sole funzioni), ho notato che se passo da paramentro una variabile per
> fargli capire al compilatore che non è una variabili d'istanza (cioé
> della funzione) ma di tutto del corpo del programma devo anteporre
> global al nome della variabile passata.

Alt alt, leggo un po' di confusione ancora prima di arrivare ai
problemi con le variabili locali e globali.
Python, come ben avrai capito, permette di scrivere codice anche
all'esterno di una classe (a differenza di Java).
Quì però mi sono perso:

"passo da parametro una variabile" = "passo una variabile per
argomento ad una funzione" ?

Poi un po' di chiarezza: Python ha sì un compilatore per trasformare
il .py in .pyc (codice oggetto) ma è un ambiente interpretato, almeno
nella sua implementazione di default. Inoltre non ha molto senso dire
"passo un parametro per fargli capire che no nè una variabile di
instanza".

Le variabili di istanza sono membri di una istanza di una classe,
ossia un oggetto. Tutte le variabili che stanno in una funzione sono
locali a quella funzione. Se invece usi "global nomevariabile"
significa che Python "bara" e va a prendere lo scope di quella
variabile nel namespace globale (il modulo in termini Python). Questo
però non ha nulla a che fare con classi, variabili di istanza ecc ecc
(al netto del fatto che in Python tutto è un oggetto, ma di questo non
ti devi preoccupare ora)

> Ok fin qua ci sono. Ma se io volessi ora mettere tutto in una classe
> come agisco? Dove definisco le variabili globali? Nella classe?

Agisci in due modi:

- impari ad usare oggetti e classi in Python leggendo questo tutorial:
http://www.greenteapress.com/thinkpython/html/book016.html

- provi a riscrivere l'esempio ;-)

> All'interno del costruttore?...

All'interno del costruttore, come in Java, procedi
all'inizializzazione dell'oggetto

> Il mio programmino di esercizio è questo sotto e praticamente non fa
> altro che sostituire il carattere "_" con uno spazio " ".

Beh per questo non è che ci sia bisogno di chissà quale architettura
ad oggetti, però teniamolo come esempio per imparare ad usarli ;)

> import os
> import string

Il modulo string non mi pare ti serva

> def rinomina_nome_file(nome_file):
>     return nome_file.replace("_", " ")
>
> def lista_file2lista_file_rinominati(lista_file):
>     global lista_file_rinominati
>     for i in range(len(lista_file)):
>         lista_file_rinominati.insert(i, rinomina_nome_file(lista_file[i]))

Invece che usare una variabile globale, di cui non vedo motivo
potresti semplicemente ritornare la lista dei file rinominati in
questo modo.

def rename_all_files(files):
  renamed_files = []
  for f in files:
    renamed_files.append(rinomina_nome_file(f))
  return renamed_files

oppure:

def rename_all_files(files):
  return [rinomina_nome_file(f) for f in files]

oppure:

def rename_all_files(files):
  for f in files:
    yield rinomina_nome_file(f)

oppure:

def rename_all_files(files):
  return (rinomina_nome_file(f) for f in files)

In questo modo le funzioni fanno quello che dovrebbero fare, ritornare
un valore ;-) E sei sicuro che se passi 2 volte una copia della stessa
lista la funzione fa sempre la stessa cosa senza modificare inutili
variabili globali

> def tree2lista_file(tree):
>     global lista_file
>     for i in tree:
>         lista_file = i[2][:]

Idem come sopra, la lista "normalizzata" dei file ritornala, non
assegnarla a qualche variabile globale:

def tree2file_list(tree):
  file_list = []
  for item in tree:
    file_list.append(list(item[2]))
  return file_list


Prova a riadattare il tuo codice con questi hint, prima di passare a
riscrivere tutto in versione object oriented



-- 
Lawrence, stacktrace.it - oluyede.org - neropercaso.it
"It is difficult to get a man to understand
something when his salary depends on not
understanding it" - Upton Sinclair


More information about the Python mailing list