Diferència entre revisions de la pàgina «Python: variables estàtiques o de classe»

De Cacauet Wiki
Salta a la navegació Salta a la cerca
 
(Hi ha una revisió intermèdia del mateix usuari que no es mostren)
Línia 17: Línia 17:
 
* ...
 
* ...
  
Accedirem a les variables d'instància a través de <code><classe>.'''__class__'''.<atribut></code>
+
<div class="exercici">
 +
Podem accedir a les variables de classe de dues maneres:
 +
<code><instancia>.'''__class__'''.<atribut></code>
 +
o bé:
 +
<code><nom_classe>.<atribut></code>
 +
</div>
  
 +
<br>
  
 
== Comptar el nombre d'instàncies creades ==
 
== Comptar el nombre d'instàncies creades ==
Línia 39: Línia 45:
  
 
=== Altres formes de fer el mateix ===
 
=== Altres formes de fer el mateix ===
Utilitzant hasattr:
+
Del què es tracta és de que no en ens "peti" el programa perquè la variable de classe no ha estat creada. Abans l'hem creat a la pròpia definició de la classe. Ara ho farem d'altres maneres.
 +
 
 +
Utilitzant ''hasattr'':
 
<syntaxhighlight lang="python">
 
<syntaxhighlight lang="python">
 
class Boto:
 
class Boto:
 
     def __init__(self):
 
     def __init__(self):
         if hasattr(self.__class__,"total"):
+
        # ens assegurem que hem creat l'atribut "total"
 +
         if hasattr(self.__class__, "total"):
 
             self.__class__.total += 1
 
             self.__class__.total += 1
 
         else:
 
         else:
 +
            # si no l'hem creat, el creem ara
 
             self.__class__.total = 1
 
             self.__class__.total = 1
 
</syntaxhighlight>
 
</syntaxhighlight>
Línia 51: Línia 61:
 
Utilitzant excepcions:
 
Utilitzant excepcions:
 
<syntaxhighlight lang="python">
 
<syntaxhighlight lang="python">
class Boto4:
+
class Boto:
 
     def __init__(self):
 
     def __init__(self):
 +
        # intentem incrementar l'atribut "total"
 
         try:
 
         try:
 
             self.__class__.total += 1
 
             self.__class__.total += 1
 
         except:
 
         except:
 +
            # si falla (excepció), el creem i inicialitzem a 1 (1a instància)
 
             self.__class__.total = 1
 
             self.__class__.total = 1
 
</syntaxhighlight>
 
</syntaxhighlight>

Revisió de 17:02, 16 des 2013

Una variables de classe o "estàtica" és una variable comuna per totes les instàncies d'una classe.


Teoria[modifica]

Els atributs o variables son:

  • D'instància: valor particular per una instància (els habituals).
  • De classe: atribut compartit per totes les instàncies.

Referències:

Aplicacions típiques:

  • Carregar en memòria elements comuns de la classe (p.ex. imatges)
  • Controlar el nombre d'instàncies creades
  • Tenir una instància única d'un objecte (singleton), p.ex. QApplication
  • ...

Podem accedir a les variables de classe de dues maneres:

<instancia>.__class__.<atribut>

o bé:

<nom_classe>.<atribut>


Comptar el nombre d'instàncies creades[modifica]

Per exemple, si tenim una interfície gràfica i volem saber quants botons hem creat:

class Boto:
    total = 0
    def __init__(self):
        self.__class__.total += 1

Aquest atribut serà comú per totes les instàncies:

>>> b1 = Boto()
>>> b1.total
1
>>> b2 = Boto()
>>> print b1.total,b2.total
(2, 2)


Altres formes de fer el mateix[modifica]

Del què es tracta és de que no en ens "peti" el programa perquè la variable de classe no ha estat creada. Abans l'hem creat a la pròpia definició de la classe. Ara ho farem d'altres maneres.

Utilitzant hasattr:

class Boto:
    def __init__(self):
        # ens assegurem que hem creat l'atribut "total"
        if hasattr(self.__class__, "total"):
            self.__class__.total += 1
        else:
            # si no l'hem creat, el creem ara
            self.__class__.total = 1

Utilitzant excepcions:

class Boto:
    def __init__(self):
        # intentem incrementar l'atribut "total"
        try:
            self.__class__.total += 1
        except:
            # si falla (excepció), el creem i inicialitzem a 1 (1a instància)
            self.__class__.total = 1


Comportaments inesperats[modifica]

ULL, perquè posar una variable en la definició de la classe no ens assegura que sigui una variable comuna a totes.

Si em vull assegurar que estic tocant la variable de classe cal accedir-hi a través de <classe/instancia>.__class__.<attr>


Mètodes estàtics[modifica]

Puc definir un mètode estàtic en un objecte mitjançant el decorator @staticmethod.

Podré accedir a les variables de classe directament sense el __class__, utilitzant el nom de la classe:

class Boto:
    total = 0
    def __init__(self):
        self.inicialitza()
        
    @staticmethod
    def inicialitza():
        Boto.total += 1