Bonjour à tous,

Je suis actuellement en train de m'arracher les cheveux sur la création d'un descripteur.

Mon problème est le suivant. Je développe un module en python pour un logiciel tiers proposant une jolie API (si on ne regarde pas de trop près). Le logiciel en question fait appel à mon module pour calculer certaines variables au cours de simulations. Le problème c'est que lors d'une simulation je ne peux afficher aucune variable (avec print), ni utiliser un debugger comme pdb. C'est relativement énervant. De plus j'ai besoin de sauvegarder quelque part les valeurs prises par certaines variables au cours de la simulation pour des post-traitements ultérieurs.

Bref, j'ai essayé quelques méthodes avec plus ou moins de succès (passer par des fichiers textes, utiliser des dictionnaire avec JSON et des "workspaces", etc...). Mais pour chacune de ces méthodes, je suis obligé de modifier mes fonctions/classes afin de « rajouter » l’enregistrement de la variable voulue. Et bien évidemment, ces variables sont ammenées à disparaitre ou de nouvelles à apparaitre.

J’ai alors pensé aux descripteurs qui je pense impliquent les modifications les plus faibles. Voici mon « Recorder » et un exemple d’utilisation associé. Le changement des attribut de l’objet en question est bien suivi, mais je ne parviens pas à différencier chaque attribut de l’objet… Ce qui est gênant.

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
52
53
54
55
# -*- coding:Utf-8 -*-
 
from weakref import WeakKeyDictionary
 
# RECORDS is a dictionary where instances and values will be stored 
RECORDS = {}
 
class Recorder(object):
    """A descriptor to track instance changes"""
    def __init__(self, default=None):
        self.data = WeakKeyDictionary()
        self.default = default
 
    def __get__(self, instance, owner):
        if instance is None:
            return self
        return self.data.get(instance, self.default)
 
    def __set__(self, instance, value):
        if instance in RECORDS.keys():
            RECORDS[instance].append(value)
        else:
            RECORDS[instance] = [value]        
        self.data[instance] = value
 
 
class MyObject(object):
    """Dummy object"""
 
    an_attribute = Recorder(0.0)
    another_attribute = Recorder(0.0)
 
    def __init__(self, name):
        self.name = name
 
    def __repr__(self):
        return self.name
 
 
if __name__ == '__main__':
 
    # Instanciation of the objects
    an_object = MyObject('an_object')
    another_object = MyObject('another_object')
 
    # Modification of the attributes
    an_object.an_attribute = 1.0
    another_object.an_attribute = 2.0
    another_object.an_attribute = 3.0
    another_object.another_attribute = 4.0
 
    # Display of the records
    print RECORDS
 
>>> {another_object: [2.0, 3.0, 4.0], an_object: [1.0]}
Est-ce que l’un de vous pourrais pointer du doigt là où il y a une erreur de raisonnement dans mon code ?

PS: Oui c'est sale de modifier le dico RECORDS comme ça...

J