Votre navigateur n'est pas à jour !

Merci de mettre à jour votre navigateur pour utiliser mon blog. Mettre à jour mon navigateur maintenant

×

Python - Self controle

Date de publication 19 janv. 2017
Quand vous utilisez python vous avez surement remarqué qu'il faut sans cesse mettre self en premier paramètre. Il correspond à l'instance en cours. Son nom n'est pas restrictif on pourrait bien avoir
def method(instance):
      print instance.attribut

La philosophie en Python est de dire "l’explicite plutôt que l’implicite". On préfère répéter l'instance sur laquelle on travail pour rendre plus clair le code.
Un autre avantage est que Python permet l'héritage multiple et d'avoir self permet d'appeler une méthode de classe (self) ou de son parent (avec le nom de la classe parente)

class Homme:
  age = 50
  def __init__(self):
    print "Homme"
  def anniversaire(self): 
    return self.age + 1   

class Femme: 
  age= 60
  def __init__(self):
    print "Femme"
  def anniversaire(self): 
    return self.age + 1   

class Personne(Homme, Femme):      
  def anniv(self): 
    age_hom = Homme.anniversaire(Homme()) 
    fem = Femme()
    age_fem = Femme.anniversaire(fem) 
    return (age_hom + age_fem) / 2

>>> inst = Personne()
Homme #Hérite de Homme en 1er
>>> inst
<__main__.Personne instance at 0xb68fd98c>
>>> inst.anniv
<bound method Personne.anniv of <__main__.Personne instance at 0xb68fd98c>>
>>> inst.anniv()
Homme
Femme
56
>>> Personne.anniv(Personne())
Homme
Homme
Femme
56
>>> Personne.anniv
<unbound method Personne.anniv>
>>> pers.anniversaire()
51 # Hérite de Homme en 1er donc 50+1

Pour hériter de toutes les classes parentes on change notre code avec super() et en héritant de object
class Homme(object):
  age = 50
  def __init__(self):
    print "Homme"
    super(Homme, self).__init__()
  def anniversaire(self): 
    return self.age + 1   

class Femme(object): 
  age= 60
  def __init__(self):
    print "Femme"
    super(Femme, self).__init__()
  def anniversaire(self): 
    return self.age + 1   

class Personne(Homme, Femme):    
  def __init__(self):
    print "Personne"
    super(Personne, self).__init__()

  def anniv(self): 
    age_hom = Homme.anniversaire(Homme()) 
    fem = Femme()
    age_fem = Femme.anniversaire(fem) 
    return (age_hom + age_fem) / 2

>>> p = Personne()
Personne
Homme
Femme

On remarque que dans la méthode anniv() de Personne on utilise 2 manières de créer une instance, mais ces 2 façons sont équivalentes. Car quand on fait :
instance = UneClasse()
instance.une_methode() 

En réalité vous faites sans le savoir :
instance = UneClasse()
UneClasse.une_methode(instance)

Donc Python a besoin de connaitre l'instance en cours pour appeler la méthode. C'est la philosophie de Python.
On peut comparer à Java qui lui utilise "this." pour se référer à l'instance.

Et nous allons voir la différence
instance.b
>> <bound method UneClasse.b of <__main__.UneCLasse instance at 0xb687a5ac>>
UneClasse.b
>> <unbound method UneClasse.b>
Bound voulant dire "lié" on remarque que instance.b est un raccourci (est lié) à UneClasse.b !

Pour ne pas passer l'instance il faut utiliser les méthodes statiques avec @staticmethod sur la méthode de la classe pour faire cela
class Carre:
  @staticmethod
  def get(x): 
  return x*x
>>> c = Carre()
>>> c.get(2)
4
>>> Carre.get(2)
4
blog comments powered by Disqus