[Python] Consiglio su utilizzo di variabili globali

enrico franchi enrico.franchi a gmail.com
Gio 8 Maggio 2008 19:14:16 CEST


2008/5/8 Mr. SpOOn <mr.spoon21 a gmail.com>:


>  Se non ho capito male, nel pattern Borg l'istanza della classe deve
>  essere unica.

Nope. E' la principale differenza fra Borg e Singleton. Con Borg puoi
fare quante istanze della classe vuoi, tuttavia lo *stato* è
condiviso.
Sono appunto come dei borg. E se non hai mai guardato star trek, fila
a guardarlo *prima* di proseguire con i design pattern! :P

>  Nella mia applicazione ho delle esigenze differenti.
>  All'interno dell'applicazione ho una classe che si occupa di
>  manipolare del testo, in pratica. Ho un'interfaccia grafica, anche,
>  quindi, graficamente, alla classe sono associate caselle di testo,
>  bottoni etc, tutti contenuti in un pannello.
>
>  L'idea è di poter avere più pannelli (quindi più istanze della classe)
>  aperti contemporaneamente, in modo da poter fare dei confronti fra
>  diversi modi di operare.
>  E, ovviamente, le variabili delle diverse istanze devono essere diverse.

Da cui segue che la variabile globale non è la cosa giusta, visto che,
per definizione, è appunto unica.
In questo caso, per inciso, non va bene nemmeno Borg. Ma diciamo che
hai descritto una mela quando volevi uno stuzzicadenti.

>  All'apertura dell'applicazione, mi interessa che si veda da subito un
>  Pannello, per questo istanzio la classe lì. Ora mi rendo conto che
>  questo forse non è molto funzionale. Insomma, non so se mi sfugge
>  qualcosa, ma se ad un certo punto mi servisse creare istanze della
>  classe Pannello, ad esempio, premendo su un bottone, come dovrei fare?
>  Non posso assegnarle a delle variabili. Qual è la soluzione in casi
>  come questo? Un metodo createPannello che mi ritorna istanze della
>  classe?

Perchè no? Ma poi perchè non puoi assegnarle a "delle variabili"?
Dopo di che è anche probabile che ci siano questioni ortogonali a
python e al design "in generale" ma strettamente dipendenti dalla tua
libreria grafica.
BTW, io su wx passo. Su Qt posso dare una manina, su Cocoa una
manuccia, su wx non proseguo con le metafore anatomiche. :)

>  Riguardo le variabili: come ho detto, la variabile "stringa" mi serve
>  all'interno di tutta la classe, ma dev'essere diversa per ogni
>  istanza. Se non ho capito male, definendola come ho fatto prima, non
>  va bene, perché avrò una variabile di classe unica e ogni istanza
>  condividerà lo stesso valore. Quindi immagino di doverle definire
>  all'interno del metodo __init__ corrispondente.

Beh, chiaramente. Cioè, non necessariamente dentro __init__. Da qualche parte.
Volendo potresti anche definire __getattr__ che se gli chiedi un
attributo di nome 'stringa' ti restituisce la stringa di default.
Quando l'hai settata invece __getattr__ non viene chiamato poichè
trova già l'attributo.

>  class Prova:
>  ...   def __init__(self):
>  ...      self.x = 5
>  ...
>
>  >>> p = Prova
>
>  >>> p
>  <class __main__.Prova at 0xb796683c>
>
>  >>> p.x
>  Traceback (most recent call last):
>   File "<stdin>", line 1, in <module>
>  AttributeError: class Prova has no attribute 'x'
>
>  Cos'è che sbaglio? Ho letto diverse cose, ma proprio non riesco a capire.

Sbagli a non avere studiato un poco! Cioè qui siamo ai fondamentali.
Tu non hai *mai* creato un istanza di Prova. Perchè se scrivi

p = Prova

p diventa un 'alias' per Prova, ma non hai mai costruito alcuna istanza Prova.

Siamo alla 'chiamata di funzione' (quale di fatto è), che in Python,
come in un buon cioppo di linguaggi si fa con le parentesi.
Oltretutto il povero interprete te lo dice pure!

>  >>> p
>  <class __main__.Prova at 0xb796683c>

Ovvero p è proprio la *classe* Prova.
Prova con, perdonandomi il gioco di parole,

p = Prova()

-- 
-enrico


Maggiori informazioni sulla lista Python