Bonjour,
pour le plaisir, mais aussi par nécessité, je me suis lancé dans la création d'un outil pour récupérer les docstrings d'un fichier Python. Voici un 1er brouillon qui montre les grandes lignes :
Le fichier test.py est le suivant :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51 #! /usr/bin/env python3 # Source : # http://docs.python.org/py3k/library/ast.html # http://pypi.python.org/pypi/pyRegurgitator/0.1.1 import ast IaNDENT_INCREASE = 4 def astStupidPrint(oneNode): """To quickly see what is done by the module "ast".""" for oneNode in ast.iter_child_nodes(astTree): print('--', oneNode._fields, ast.dump(oneNode), sep="\n") def docstringPrint(oneNode, indentLevel = -INDENT_INCREASE, className = '', infoToPrint = ''): #print(type(oneNode)) if isinstance(oneNode, ast.Expr) and isinstance(oneNode.value, ast.Str): print(' '*indentLevel + '=== DOCSTRING {} ==='.format(infoToPrint), ' '*(indentLevel + INDENT_INCREASE) + oneNode.value.s.replace('\n', '\n' + ' '*(indentLevel + INDENT_INCREASE)), sep="\n") elif 'body' in oneNode._fields: if isinstance(oneNode, ast.FunctionDef): if className: infoToPrint = 'METHOD OF "{0}" :: {1}'.format(className, oneNode.name) else: infoToPrint = 'FUNCTION :: ' + oneNode.name elif isinstance(oneNode, ast.ClassDef): infoToPrint = 'CLASS :: ' + oneNode.name className = oneNode.name else: infoToPrint = 'CURRENT MODULE OR FILE' content = getattr(oneNode, 'body') if content: for onePiece in content: docstringPrint(oneNode = onePiece, indentLevel = indentLevel + INDENT_INCREASE, className = className, infoToPrint = infoToPrint) if __name__ == '__main__': file = open('test.py') astTree = ast.parse(file.read()) # astStupidPrint(astTree) # print() docstringPrint(astTree)
Ceci me renvoie :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23 #! /usr/bin/env python3 """1ère doc du fichier sur deux lignes""" def myFunction(x=0, y="1"): """Doc de la fonction nommée myFunction""" x=3 # Un commentaire. z = x+y return z """2nde docstring mal placée...""" print(myFunction(5,6)) class bidon(): """Doc de la classe bidon""" def __init__(self): """1ère doc de la méthode __init__ de la classe bidon""" ... """2ème doc mal placée de la méthode __init__"""
J'essaierais d'améliorer ceci pour obtenir un mini outil de documentation à la sauce epydoc mais en plus facile à personnaliser.
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13 === DOCSTRING CURRENT MODULE OR FILE === 1ère doc du fichier sur deux lignes === DOCSTRING FUNCTION :: myFunction === Doc de la fonction nommée myFunction === DOCSTRING CURRENT MODULE OR FILE === 2nde docstring mal placée... === DOCSTRING CLASS :: bidon === Doc de la classe bidon === DOCSTRING METHOD OF "bidon" :: __init__ === 1ère doc de la méthode __init__ de la classe bidon === DOCSTRING METHOD OF "bidon" :: __init__ === 2ème doc mal placée de la méthode __init__
De plus en ayant toutes les docstrings, on peut envisager un moyen de faire des tutos qui affichent le code morcelé avec entre chaque morceau des commentaires en ayant juste à taper quelque chose comme :
Ensuite un petit prog. Python donnerait la mise en forme suivante :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7 for i in range(5): print(i) """ Nous avons ici une première façon de taper une boucle...""" i = 0 while(i < 5): print(i) """Voici une autre méthode pour obtenir le même résultat que précédemment..."""
PS : merci à nardo47 de m'avoir dirigé vers ast.Nous avons ici une première façon de taper une boucle...
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2 for i in range(5): print(i)
Voici une autre méthode pour obtenir le même résultat que précédemment...
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3 i = 0 while(i < 5): print(i)
Partager