Fabrication industrielle
Internet des objets industriel | Matériaux industriels | Entretien et réparation d'équipement | Programmation industrielle |
home  MfgRobots >> Fabrication industrielle >  >> Industrial programming >> Python

Maîtriser la programmation orientée objet en Python : Guide complet

Python est un langage orienté objet depuis son origine. Créer et utiliser des classes et des objets est donc très simple. Ce chapitre vous aide à devenir expert dans l'utilisation du support de la programmation orientée objet (POO) de Python.

Si vous n'avez aucune expérience de la programmation orientée objet (POO), consultez un cours d'introduction ou au moins un tutoriel pour saisir les concepts de base.

Voici une petite introduction à la POO pour vous mettre à niveau :

Vue d'ensemble de la terminologie POO

Création de classes

L'instruction class crée une nouvelle définition de classe. Le nom de la classe suit immédiatement le mot-clé class suivi de deux points :

class ClassName:
    'Optional class documentation string'
    class_suite

Exemple

Voici un exemple de classe Python simple :

class Employee:
    'Common base class for all employees'
    empCount = 0

    def __init__(self, name, salary):
        self.name = name
        self.salary = salary
        Employee.empCount += 1

    def displayCount(self):
        print("Total Employee %d" % Employee.empCount)

    def displayEmployee(self):
        print("Name : ", self.name, ", Salary: ", self.salary)

Création d'objets instances

Pour créer des instances d'une classe, appelez la classe en utilisant son nom et passez les arguments acceptés par sa méthode __init__ :

# Ceci créerait le premier objet de la classe Employee
emp1 = Employee("Zara", 2000)
# Ceci créerait le second objet
emp2 = Employee("Manni", 5000)

Accès aux attributs

Vous accédez aux attributs de l'objet via l'opérateur point. Les variables de classe sont accessibles via le nom de la classe :

emp1.displayEmployee()
emp2.displayEmployee()
print("Total Employee %d" % Employee.empCount)

En rassemblant tous les concepts :

#!/usr/bin/python
class Employee:
    'Common base class for all employees'
    empCount = 0

    def __init__(self, name, salary):
        self.name = name
        self.salary = salary
        Employee.empCount += 1

    def displayCount(self):
        print("Total Employee %d" % Employee.empCount)

    def displayEmployee(self):
        print("Name : ", self.name, ", Salary: ", self.salary)

emp1 = Employee("Zara", 2000)
emp2 = Employee("Manni", 5000)
emp1.displayEmployee()
emp2.displayEmployee()
print("Total Employee %d" % Employee.empCount)

Résultat :

Name : Zara ,Salary: 2000
Name : Manni ,Salary: 5000
Total Employee 2

Vous pouvez ajouter, supprimer ou modifier des attributs de classes et d'objets à tout moment :

emp1.age = 7  # Ajouter un attribut 'age'
emp1.age = 8  # Modifier 'age'
del emp1.age  # Supprimer 'age'

Au lieu d'utiliser les instructions normales, vous pouvez utiliser les fonctions suivantes :

hasattr(emp1, 'age')    # True si 'age' existe
getattr(emp1, 'age')    # Valeur de 'age'
setattr(emp1, 'age', 8) # Définir 'age' à 8
delattr(emp1, 'age')    # Supprimer 'age'

Attributs de classe intégrés

Chaque classe Python conserve les attributs intégrés suivants, accessibles via l'opérateur point :

Pour la classe ci-dessus, accédons à ces attributs :

#!/usr/bin/python
class Employee:
    'Common base class for all employees'
    empCount = 0
    def __init__(self, name, salary):
        self.name = name
        self.salary = salary
        Employee.empCount += 1
    def displayCount(self):
        print("Total Employee %d" % Employee.empCount)
    def displayEmployee(self):
        print("Name : ", self.name, ", Salary: ", self.salary)

print("Employee.__doc__:", Employee.__doc__)
print("Employee.__name__:", Employee.__name__)
print("Employee.__module__:", Employee.__module__)
print("Employee.__bases__:", Employee.__bases__)
print("Employee.__dict__:", Employee.__dict__)

Résultat :

Employee.__doc__: Common base class for all employees
Employee.__name__: Employee
Employee.__module__: __main__
Employee.__bases__: ()
Employee.__dict__: {'__module__': '__main__', 'displayCount': , 'empCount': 2, 'displayEmployee': , '__doc__': 'Common base class for all employees', '__init__': }

Destruction d'objets (Ramasse-miettes)

Python supprime automatiquement les objets inutiles (types intégrés ou instances de classes) pour libérer l'espace mémoire. Le processus par lequel Python récupère périodiquement les blocs de mémoire plus utilisés s'appelle la collecte des ordures (Garbage Collection).

Le ramasse-miettes s'exécute pendant le programme et se déclenche quand le compteur de références d'un objet atteint zéro. Ce compteur change selon le nombre d'alias pointant vers l'objet.

Le compteur augmente quand l'objet reçoit un nouveau nom ou est placé dans un conteneur (liste, tuple, dictionnaire). Il diminue quand l'objet est supprimé avec del, sa référence réassignée, ou sort de portée. À zéro, Python le collecte automatiquement.

a = 40      # Créer objet <40>
b = a       # Augmenter ref. count de <40>
c = [b]     # Augmenter ref. count de <40>
del a       # Diminuer ref. count de <40>
b = 100     # Diminuer ref. count de <40>
c[0] = -1   # Diminuer ref. count de <40>

Vous ne remarquerez normalement pas quand le ramasse-miettes détruit une instance orpheline. Mais une classe peut implémenter la méthode spéciale __del__(), appelée destructeur, invoquée quand l'instance est sur le point d'être détruite. Cette méthode peut nettoyer les ressources non-mémoire utilisées par une instance.

Exemple

Ce destructeur __del__() affiche le nom de la classe d'une instance sur le point d'être détruite :

#!/usr/bin/python
class Point:
    def __init__(self, x=0, y=0):
        self.x = x
        self.y = y
    def __del__(self):
        class_name = self.__class__.__name__
        print(class_name, "destroyed")

pt1 = Point()
pt2 = pt1
pt3 = pt1
print(id(pt1), id(pt2), id(pt3))
del pt1
del pt2
del pt3

Résultat :

3083401324 3083401324 3083401324
Point destroyed

Note : Idéalement, définissez vos classes dans un fichier séparé, puis importez-les dans votre programme principal avec import.

Héritage de classe

Au lieu de partir de zéro, créez une classe en la dérivant d'une classe préexistante en listant la classe parente entre parenthèses après le nom de la nouvelle classe.

La classe enfant hérite des attributs de sa classe parente et peut les utiliser comme si elles étaient définies dans la classe enfant. Une classe enfant peut aussi redéfinir des membres de données et des méthodes du parent.

Syntaxe

class SubClassName (ParentClass1[, ParentClass2, ...]):
    'Optional class documentation string'
    class_suite

Exemple

#!/usr/bin/python
class Parent:
    parentAttr = 100
    def __init__(self):
        print("Calling parent constructor")
    def parentMethod(self):
        print('Calling parent method')
    def setAttr(self, attr):
        Parent.parentAttr = attr
    def getAttr(self):
        print("Parent attribute :", Parent.parentAttr)

class Child(Parent):
    def __init__(self):
        print("Calling child constructor")
    def childMethod(self):
        print('Calling child method')

c = Child()
c.childMethod()
c.parentMethod()
c.setAttr(200)
c.getAttr()

Résultat :

Calling child constructor
Calling child method
Calling parent method
Parent attribute : 200

De même, vous pouvez dériver une classe de plusieurs classes parentes :

class A:
    # définir votre classe A .....
class B:
    # définir votre classe B .....
class C(A, B):
    # sous-classe de A et B .....

Utilisez issubclass() ou isinstance() pour vérifier les relations entre classes et instances :

Redéfinition de méthodes

Vous pouvez toujours redéfinir les méthodes de votre classe parente. Une raison : vous voulez une fonctionnalité spéciale ou différente dans votre sous-classe.

Exemple

#!/usr/bin/python
class Parent:
    def myMethod(self):
        print('Calling parent method')

class Child(Parent):
    def myMethod(self):
        print('Calling child method')

c = Child()
c.myMethod()

Résultat :

Calling child method

Méthodes de base surchargeables

Le tableau suivant liste quelques fonctionnalités génériques que vous pouvez redéfinir dans vos classes :

N°Méthode, description et exemple d'appel
1

__init__(self[, args...])

Constructeur (avec arguments optionnels)

Appel : obj = className(args)

2

__del__(self)

Destructeur, supprime un objet

Appel : del obj

3

__repr__(self)

Représentation chaîne évaluable

Appel : repr(obj)

4

__str__(self)

Représentation chaîne affichable

Appel : str(obj)

5

__cmp__(self, x)

Comparaison d'objets

Appel : cmp(obj, x)

Surcharge d'opérateurs

Supposons que vous ayez créé une classe Vector pour représenter des vecteurs 2D. Que se passe-t-il avec l'opérateur plus ? Python protestera probablement.

Vous pouvez définir la méthode __add__ dans votre classe pour effectuer l'addition vectorielle, et l'opérateur plus se comportera comme attendu :

Exemple

#!/usr/bin/python
class Vector:
    def __init__(self, a, b):
        self.a = a
        self.b = b
    def __str__(self):
        return 'Vector (%d, %d)' % (self.a, self.b)
    def __add__(self, other):
        return Vector(self.a + other.a, self.b + other.b)

v1 = Vector(2, 10)
v2 = Vector(5, -2)
print(v1 + v2)

Résultat :

Vector(7, 8)

Masquage des données

Les attributs d'un objet peuvent être visibles ou non en dehors de la définition de la classe. Nommez les attributs avec un double underscore comme préfixe, et ils ne seront pas directement visibles depuis l'extérieur.

Exemple

#!/usr/bin/python
class JustCounter:
    __secretCount = 0
    def count(self):
        self.__secretCount += 1
        print(self.__secretCount)

counter = JustCounter()
counter.count()
counter.count()
print(counter.__secretCount)

Résultat :

1
2
Traceback (most recent call last):
  File "test.py", line 12, in 
    print(counter.__secretCount)
AttributeError: JustCounter instance has no attribute '__secretCount'

Python protège ces membres en changeant internement le nom pour inclure le nom de la classe. Vous pouvez accéder à de tels attributs via object._className__attrName. Si vous remplacez la dernière ligne par :

print(counter._JustCounter__secretCount)

Résultat :

1
2
2

Python

  1. Classes et objets C# : Fondations pour une POO robuste
  2. Maîtriser les types de données Python : Guide pratique
  3. Maîtriser les opérateurs Python : Guide complet
  4. Maîtriser l'instruction pass en Python : Guide pratique
  5. Maîtriser les dictionnaires Python : création, manipulation et techniques avancées
  6. Maîtriser les exceptions personnalisées Python : guide pratique
  7. Maîtriser la programmation orientée objet Python : classes, héritage, encapsulation et polymorphisme
  8. Le pattern Singleton en Java expliqué : implémentation et utilisation sûre
  9. Suivi d'objets automatisé par vision avec Raspberry Pi et OpenCV