Python orienté objet - blocs de construction
Dans ce chapitre, nous discuterons en détail des termes orientés objet et des concepts de programmation. La classe est juste une fabrique pour une instance. Cette fabrique contient le plan directeur qui décrit comment créer les instances. Une instance ou un objet sont construits à partir de la classe. Dans la plupart des cas, nous pouvons avoir plus d'une instance d'une classe. Chaque instance a un ensemble d'attributs et ces attributs sont définis dans une classe, de sorte que chaque instance d'une classe particulière est censée avoir les mêmes attributs.
Packs de classes: comportement et état
Une classe vous permettra de regrouper le comportement et l'état d'un objet. Observez le schéma suivant pour une meilleure compréhension -
Les points suivants méritent d'être notés lors de la discussion des groupes de classes -
Le mot behavior est identique à function - c'est un morceau de code qui fait quelque chose (ou implémente un comportement)
Le mot state est identique à variables - c'est un endroit pour stocker des valeurs dans une classe.
Lorsque nous affirmons un comportement et un état de classe ensemble, cela signifie qu'une classe regroupe des fonctions et des variables.
Les classes ont des méthodes et des attributs
En Python, la création d'une méthode définit un comportement de classe. Le mot méthode est le nom POO donné à une fonction définie dans une classe. Pour résumer -
Class functions - est synonyme de methods
Class variables - est synonyme de name attributes.
Class - un plan pour une instance avec un comportement exact.
Object - l'une des instances de la classe, exécute la fonctionnalité définie dans la classe.
Type - indique la classe à laquelle appartient l'instance
Attribute - Toute valeur d'objet: object.attribute
Method - un «attribut appelable» défini dans la classe
Observez le morceau de code suivant par exemple -
var = “Hello, John”
print( type (var)) # ‘str’> or <class 'str'>
print(var.upper()) # upper() method is called, HELLO, JOHN
Création et instanciation
Le code suivant montre comment créer notre première classe, puis son instance.
class MyClass(object):
pass
# Create first instance of MyClass
this_obj = MyClass()
print(this_obj)
# Another instance of MyClass
that_obj = MyClass()
print (that_obj)
Ici, nous avons créé une classe appelée MyClasset qui ne fait aucune tâche. L'argumentobject dans MyClass class implique l'héritage de classe et sera discuté dans les chapitres suivants. pass dans le code ci-dessus indique que ce bloc est vide, c'est-à-dire qu'il s'agit d'une définition de classe vide.
Créons une instance this_obj de MyClass() classe et imprimez-le comme indiqué -
<__main__.MyClass object at 0x03B08E10>
<__main__.MyClass object at 0x0369D390>
Ici, nous avons créé une instance de MyClass.Le code hexadécimal fait référence à l'adresse où l'objet est stocké. Une autre instance pointe vers une autre adresse.
Définissons maintenant une variable à l'intérieur de la classe MyClass() et récupérez la variable de l'instance de cette classe comme indiqué dans le code suivant -
class MyClass(object):
var = 9
# Create first instance of MyClass
this_obj = MyClass()
print(this_obj.var)
# Another instance of MyClass
that_obj = MyClass()
print (that_obj.var)
Production
Vous pouvez observer la sortie suivante lorsque vous exécutez le code donné ci-dessus -
9
9
Comme l'instance sait à partir de quelle classe elle est instanciée, ainsi, lorsqu'elle est demandée pour un attribut d'une instance, l'instance recherche l'attribut et la classe. C'est ce qu'on appelle leattribute lookup.
Méthodes d'instance
Une fonction définie dans une classe est appelée method.Une méthode d'instance nécessite une instance pour l'appeler et ne nécessite aucun décorateur. Lors de la création d'une méthode d'instance, le premier paramètre est toujoursself. Bien que nous puissions l'appeler (self) par n'importe quel autre nom, il est recommandé d'utiliser self, car c'est une convention de dénomination.
class MyClass(object):
var = 9
def firstM(self):
print("hello, World")
obj = MyClass()
print(obj.var)
obj.firstM()
Production
Vous pouvez observer la sortie suivante lorsque vous exécutez le code donné ci-dessus -
9
hello, World
Notez que dans le programme ci-dessus, nous avons défini une méthode avec self comme argument. Mais nous ne pouvons pas appeler la méthode car nous n'y avons déclaré aucun argument.
class MyClass(object):
def firstM(self):
print("hello, World")
print(self)
obj = MyClass()
obj.firstM()
print(obj)
Production
Vous pouvez observer la sortie suivante lorsque vous exécutez le code donné ci-dessus -
hello, World
<__main__.MyClass object at 0x036A8E10>
<__main__.MyClass object at 0x036A8E10>
Encapsulation
L'encapsulation est l'un des principes fondamentaux de la POO. La POO permet de masquer la complexité du fonctionnement interne de l'objet qui est avantageuse pour le développeur de la manière suivante -
Simplifie et rend facile de comprendre l'utilisation d'un objet sans connaître les éléments internes.
Tout changement peut être facilement gérable.
La programmation orientée objet repose fortement sur l'encapsulation. Les termes encapsulation et abstraction (également appelés masquage de données) sont souvent utilisés comme synonymes. Ils sont presque synonymes, car l'abstraction est réalisée par l'encapsulation.
L'encapsulation nous fournit le mécanisme de restriction de l'accès à certains des composants de l'objet, cela signifie que la représentation interne d'un objet ne peut pas être vue de l'extérieur de la définition de l'objet. L'accès à ces données se fait généralement par des méthodes spéciales -Getters et Setters.
Ces données sont stockées dans des attributs d'instance et peuvent être manipulées de n'importe où en dehors de la classe. Pour le sécuriser, ces données ne doivent être accessibles qu'à l'aide de méthodes d'instance. L'accès direct ne devrait pas être autorisé.
class MyClass(object):
def setAge(self, num):
self.age = num
def getAge(self):
return self.age
zack = MyClass()
zack.setAge(45)
print(zack.getAge())
zack.setAge("Fourty Five")
print(zack.getAge())
Production
Vous pouvez observer la sortie suivante lorsque vous exécutez le code donné ci-dessus -
45
Fourty Five
Les données ne doivent être stockées que si elles sont correctes et valides, à l'aide de constructions de gestion des exceptions. Comme nous pouvons le voir ci-dessus, il n'y a aucune restriction sur l'entrée de l'utilisateur dans la méthode setAge (). Cela peut être une chaîne, un nombre ou une liste. Nous devons donc vérifier le code ci-dessus pour garantir l'exactitude du stockage.
class MyClass(object):
def setAge(self, num):
self.age = num
def getAge(self):
return self.age
zack = MyClass()
zack.setAge(45)
print(zack.getAge())
zack.setAge("Fourty Five")
print(zack.getAge())
Constructeur d'initiation
Le __initLa méthode __ est appelée implicitement dès qu'un objet d'une classe est instancié, ce qui initialisera l'objet.
x = MyClass()
La ligne de code ci-dessus créera une nouvelle instance et affectera cet objet à la variable locale x.
L'opération d'instanciation, c'est-à-dire calling a class object, crée un objet vide. De nombreuses classes aiment créer des objets avec des instances personnalisées selon un état initial spécifique. Par conséquent, une classe peut définir une méthode spéciale nommée '__init __ ()' comme indiqué -
def __init__(self):
self.data = []
Python appelle __init__ pendant l'instanciation pour définir un attribut supplémentaire qui doit se produire lorsqu'une classe est instanciée et qui peut être en train de configurer des valeurs de début pour cet objet ou d'exécuter une routine requise lors de l'instanciation. Ainsi, dans cet exemple, une nouvelle instance initialisée peut être obtenue par -
x = MyClass()
La méthode __init __ () peut avoir un ou plusieurs arguments pour une plus grande flexibilité. L'initialisation signifie initialisation, car il initialise les attributs de l'instance. Il est appelé le constructeur d'une classe.
class myclass(object):
def __init__(self,aaa, bbb):
self.a = aaa
self.b = bbb
x = myclass(4.5, 3)
print(x.a, x.b)
Production
4.5 3
Attributs de classe
L'attribut défini dans la classe est appelé «attributs de classe» et les attributs définis dans la fonction sont appelés «attributs d'instance». Lors de la définition, ces attributs ne sont pas préfixés par self, car ils sont la propriété de la classe et non d'une instance particulière.
Les attributs de classe sont accessibles par la classe elle-même (className.attributeName) ainsi que par les instances de la classe (inst.attributeName). Ainsi, les instances ont accès à la fois à l'attribut d'instance et aux attributs de classe.
>>> class myclass():
age = 21
>>> myclass.age
21
>>> x = myclass()
>>> x.age
21
>>>
Un attribut de classe peut être remplacé dans une instance, même si ce n'est pas une bonne méthode pour interrompre l'encapsulation.
Il existe un chemin de recherche pour les attributs en Python. Le premier étant la méthode définie dans la classe, puis la classe au-dessus.
>>> class myclass(object):
classy = 'class value'
>>> dd = myclass()
>>> print (dd.classy) # This should return the string 'class value'
class value
>>>
>>> dd.classy = "Instance Value"
>>> print(dd.classy) # Return the string "Instance Value"
Instance Value
>>>
>>> # This will delete the value set for 'dd.classy' in the instance.
>>> del dd.classy
>>> >>> # Since the overriding attribute was deleted, this will print 'class
value'.
>>> print(dd.classy)
class value
>>>
Nous remplaçons l'attribut de classe «classy» dans l'instance dd. Lorsqu'il est remplacé, l'interpréteur Python lit la valeur remplacée. Mais une fois que la nouvelle valeur est supprimée avec «del», la valeur remplacée n'est plus présente dans l'instance, et par conséquent, la recherche passe un niveau supérieur et l'obtient de la classe.
Utilisation des données de classe et d'instance
Dans cette section, voyons comment les données de classe sont liées aux données d'instance. Nous pouvons stocker des données dans une classe ou dans une instance. Lorsque nous concevons une classe, nous décidons quelles données appartiennent à l'instance et quelles données doivent être stockées dans la classe globale.
Une instance peut accéder aux données de classe. Si nous créons plusieurs instances, ces instances peuvent accéder à leurs valeurs d'attribut individuelles ainsi qu'aux données globales de la classe.
Ainsi, une donnée de classe est la donnée qui est partagée entre toutes les instances. Observez le code ci-dessous pour une meilleure compréhension -
class InstanceCounter(object):
count = 0 # class attribute, will be accessible to all instances
def __init__(self, val):
self.val = val
InstanceCounter.count +=1 # Increment the value of class attribute, accessible through class name
# In above line, class ('InstanceCounter') act as an object
def set_val(self, newval):
self.val = newval
def get_val(self):
return self.val
def get_count(self):
return InstanceCounter.count
a = InstanceCounter(9)
b = InstanceCounter(18)
c = InstanceCounter(27)
for obj in (a, b, c):
print ('val of obj: %s' %(obj.get_val())) # Initialized value ( 9, 18, 27)
print ('count: %s' %(obj.get_count())) # always 3
Production
val of obj: 9
count: 3
val of obj: 18
count: 3
val of obj: 27
count: 3
En bref, les attributs de classe sont les mêmes pour toutes les instances de classe tandis que les attributs d'instance sont particuliers pour chaque instance. Pour deux instances différentes, nous aurons deux attributs d'instance différents.
class myClass:
class_attribute = 99
def class_method(self):
self.instance_attribute = 'I am instance attribute'
print (myClass.__dict__)
Production
Vous pouvez observer la sortie suivante lorsque vous exécutez le code donné ci-dessus -
{'__module__': '__main__', 'class_attribute': 99, 'class_method':
, '__dict__':
, '__weakref__':
, '__doc__': None}
The instance attribute myClass.__dict__ as shown −
>>> a = myClass()
>>> a.class_method()
>>> print(a.__dict__)
{'instance_attribute': 'I am instance attribute'}