Skip to content
This repository was archived by the owner on May 7, 2021. It is now read-only.
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
72 changes: 29 additions & 43 deletions source/dunders/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -11,47 +11,25 @@ Introduction

Le mot dunder est un raccourci de *Double UNDERscore* et représente toutes les méthodes Python qui commencent et finissent par un double underscore (par ex. ``__init__()``).

Les dunders sont des méthodes très puissantes et régulièrement utilisées en python. Ce sont des méthodes universelles que toute classe possède (un peu à l'image de la class Object dans Java).
Les dunders sont des méthodes universelles de python. Chacun des dunders est lié à une méthode qui sera implicitement appelée lorsqu'on fait appel au dunder (ce qui fait qu'elles sont également appelés méthodes magiques). De ce fait, on utilise fréquemment des dunders sans s'en rendre compte.

.. Quel lien entre Object de Java et les dunders?

Cependant, dans python, les dunders sont rarement appelés directement.

.. todo:: Un peu imprécis car il n'y a pas que des méthodes. ``__name__`` ou ``__file__``

Par exemple :
par exemple :

.. code-block:: python3

toto = new MyClass()


fera appel aux méthodes ``__new__()`` et ``__init__()`` même si ces méthodes n'ont pas été surchargées.

.. c'est un peu la base de la programmation orienté objet...

Les dunders ont des méthodes raccourci qui vont directement les appeler (autre raison pour laquelle on utilise régulièrement les dunders sans s'en rendre compte) :

.. code-block:: pycon
x = MyClass() #fera appel au dunder __init__() de la classe MyClass
str(x) #fera appel au dunder __str__() de la classe MyClass
str(12) #fera appel au dunder __str__() de la classe Integer
add = 4 + 5 # fera appel au dunder ``__add__()`` de la classe Number

>>> 4 + 5
9

Les dunders fonctionnent églaement d'autres éléments que des classes, par exemple le dunder *__name__* permet de connaitre le nom du module utilisé, pratique quand on veut exécuter certaines fonctions uniquement lors de l'exécution d'un module et pas lors de son import :

fera appel au dunder ``__add__()``

.. de quelle classe? puisque c'est une méthode.
.. literalinclude:: name_dunder.py

Ou bien :

.. code-block:: python3

str("I'm a text")


fera appel au dunder ``__str__()`` de :py:class:`str`.

.. obtenir la chaine de caractère d'une chaine de caractère, n'est pas le meilleur exemple.
Dans le même registre, un package nécessite d'avoir un fichier __init__.py qui s'exécute automatiquement lors de l'import dudit package.

La grande puissance des dunders est leur universalité. En effet, Python a été programmé de manière à ce qu'une opération soit toujours relié au même *dunder*.

Expand All @@ -66,18 +44,6 @@ Voir: `Python and the Principle of Least Astonishment <http://lucumr.pocoo.org/2

Une autre grande utilisation des dunders consiste à les surcharger de manière à les personalisé.

De plus, par convention, on déclare une méthode privée comme étant un dunder :

.. code-block:: python3

def __myPrivateMethod__(self, other):
return none;

.. todo:: Ceci est faux! On n'invente pas de *dunders* personnels, jamais.

:pep:`8`


Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Du coup, expliquez pour les méthodes privées. Vous n'étiez pas loin de la vérité.

Exemples
========

Expand Down Expand Up @@ -106,12 +72,32 @@ De base, quand on chercher à afficher un objet, à moins que la méthode ``__st

Idéalement, il faudrait toujours redéfinir la méthode ``__repr__()`` et redéfinir ``__str__()`` uniquement si on a besoin de l'ambiguïté.


Membres privées
================

Bien que n'étant pas un dunder, un membre commençant pas un double underscore sera considéré comme étant un membre privé :


.. code-block:: python3

__private_attribut = 12


Cependant, cette pratique est déconseillée en python car rien n'est vraiment privé et il sera toujours possible d'accéder à *__private_attribut*. Par convension, on utilise un seul undersecore pour signaler qu'un méthode est privée et après c'est à la responsabilité du développeur de ne pas faire n'importe quoi. "We are all adults here"


Conclusion
==========

Il existe beaucoup de dunders. Il faut puiser dans la doc afin de connaitre ceux dont on a l'usage et savoir quand ils sont utilisés.
Ce sont de puissants outils de Python qui permettent de facilement spécialiser le comportement d'un objet.

Documentation officielle
-------------------------

https://docs.python.org/3/reference/datamodel.html
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

avec intersphinx.


Bibliographie
=============

Expand Down
10 changes: 5 additions & 5 deletions source/dunders/main.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
"""Travis est trop compliqué."""
"""Exemple d'utilisation des dunders."""


class Main:
Expand All @@ -8,8 +8,8 @@ def __init__(self, *args):
"""Initialisateur."""
self.cartes = args

def ajouter(self, carte):
"""Méthode pour add une carte."""
def __add__(self, carte):
"""Redéfinition de l'opérateur + pour add une carte."""
obj2 = list(self.cartes) # Converti en liste
obj2.append(carte)
self.cartes = tuple(obj2)
Expand Down Expand Up @@ -42,9 +42,9 @@ def __contains__(self, item):
main = Main('1Coeur', '7Pique')
print(str(main))

main.ajouter('AsCoeur')
main+'AsCoeur'

# parc qu'on a défini __iter__!
# parce qu'on a défini __iter__!
for carte in main:
print(carte)

Expand Down
14 changes: 14 additions & 0 deletions source/dunders/name_dunder.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
"""Module d'exemple utilisant le dunder __name__."""


def some_function():
"""Affiche une simple phrase."""
print("I'm a script")


if __name__ == '__main__':
"""
some_function ne s'exécute que si on lance directement le module
et pas si on l'importe.
"""
some_function()
2 changes: 1 addition & 1 deletion source/dunders/someclass.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
"""Travis est très très compliqué."""
"""Exemple d'utilisation des dunders."""


class SomeClass:
Expand Down
2 changes: 1 addition & 1 deletion source/dunders/vector.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
"""Travis est très compliqué."""
"""Exemple d'utilisation des dunders."""
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

😍



from math import hypot
Expand Down