IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Python Discussion :

Sauvegarder les objets eux-mêmes plutôt que la valeur de leurs attributs ?


Sujet :

Python

  1. #1
    Membre à l'essai
    Homme Profil pro
    Architecte réseau
    Inscrit en
    Janvier 2016
    Messages
    36
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 53
    Localisation : France, Finistère (Bretagne)

    Informations professionnelles :
    Activité : Architecte réseau

    Informations forums :
    Inscription : Janvier 2016
    Messages : 36
    Points : 19
    Points
    19
    Par défaut Sauvegarder les objets eux-mêmes plutôt que la valeur de leurs attributs ?
    Bonjour,

    Je suis en train de m'attaquer à la sauvegarde des paramètres d'objets "serie" (Classe d'objets contenant des données devant âtre tracée sur un graphique ainsi que les différents paramètres du graphique en question)
    et je comptais sauvegarder tout ça dans un fichier texte pour pouvoir ensuite réimporter le tout et reparamétrer mes objets à l'identique d'une session à l'autre... Puis je me suis souvenu que pickle permettait de sauvegarder des objets. Donc je me dis que plutôt que de décortiquer mes objet pour en faire des chaines et ensuite devoir tout refaire à l'inverse pour reconstruire mes objets, il serait préférable de sauvegarder les objets eux-même et de les recharger la session suivante et puis c'est tout...
    J'ai donc commencer à écrire ça
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    def save_series_objects():
    	global dict_of_series
    	saving_filename = "saved_series.txt"
    	with open(saving_filename, 'wb') as f:
    		print(type(dict_of_series))
    		print(dict_of_series)
    		pickle.dump(dict_of_series, f, protocol=pickle.HIGHEST_PROTOCOL)
    Ce que je tente de sauvegarder est un dictionnaire (dict_of_series) qui contient tout mes objets "serie"

    les print en console donnent
    <class 'dict'>
    {'Temperature1': <__main__.SensorSeries object at 0x088AA330>, 'Temperature2': <__main__.SensorSeries object at 0x088AAA30>, 'Temperature3': <__main__.SensorSeries object at 0x088AAFB0>, 'Current': <__main__.SensorSeries object at 0x0888D670>, 'Hydrogen': <__main__.SensorSeries object at 0x0888D5F0>, 'Pressure': <__main__.SensorSeries object at 0x0888DA50>}


    mais j'ai une erreur


    line 375, in save_series_objects
    pickle.dump(dict_of_series, f, protocol=pickle.HIGHEST_PROTOCOL)
    TypeError: 'NoneType' object is not callable



    Je ne comprend pas où est l'erreur...

  2. #2
    Membre à l'essai
    Homme Profil pro
    Architecte réseau
    Inscrit en
    Janvier 2016
    Messages
    36
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 53
    Localisation : France, Finistère (Bretagne)

    Informations professionnelles :
    Activité : Architecte réseau

    Informations forums :
    Inscription : Janvier 2016
    Messages : 36
    Points : 19
    Points
    19
    Par défaut
    Je me suis peut-être mépris sur l'usage de pickle. Il ne peut peut-être pas sauvegarder n'importe quel objet ?

  3. #3
    Membre à l'essai
    Homme Profil pro
    Architecte réseau
    Inscrit en
    Janvier 2016
    Messages
    36
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 53
    Localisation : France, Finistère (Bretagne)

    Informations professionnelles :
    Activité : Architecte réseau

    Informations forums :
    Inscription : Janvier 2016
    Messages : 36
    Points : 19
    Points
    19
    Par défaut
    J'ai un peu plus d'infos:
    En mode Debug sous Pycharm, à l'exécution de
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    pickle.dump(dict_of_series, f, protocol=pickle.HIGHEST_PROTOCOL)
    , cela appel une méthode de ma classe "serie" (ce sont les instances de serie qui sont stockées dans le dictionnaire "dict_of_series")
    La méthode appelée est :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    	def __getattr__(self, attribut_name):
    		"""
                    If the attribut_name does not exist... tell it !
                    """
    		print('Pas glop !')
    		print(f'!-->{attribut_name}<--! Does not exist here !')
    Le problème vient de là ; l'argument passé lors de l'appel est : attribut_name: '__getstate__'
    seulement ma classe ne contient pas (à priori) d’attribut nommé '__getstate__' ...

    du coup la console me renvoie
    Pas glop !
    !-->__getstate__<--! Does not exist here !


    et à partir de là je perd le fil pour le moment...

  4. #4
    Expert éminent sénior
    Homme Profil pro
    Architecte technique retraité
    Inscrit en
    Juin 2008
    Messages
    21 283
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Manche (Basse Normandie)

    Informations professionnelles :
    Activité : Architecte technique retraité
    Secteur : Industrie

    Informations forums :
    Inscription : Juin 2008
    Messages : 21 283
    Points : 36 770
    Points
    36 770
    Par défaut
    Salut,

    Citation Envoyé par scarou Voir le message
    et à partir de là je perd le fil pour le moment...
    Cà veut juste dire qu'une classe qui définit la méthode __getattr__ n'est pas "pickable" sans définir __getstate__. Ce qui se comprend, car, par défaut, pickle va récupérer l'état de l'instance dans son .__dict__. Avec __getattr__, ils peuvent être n'importe où...

    - W
    Architectures post-modernes.
    Python sur DVP c'est aussi des FAQs, des cours et tutoriels

  5. #5
    Membre à l'essai
    Homme Profil pro
    Architecte réseau
    Inscrit en
    Janvier 2016
    Messages
    36
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 53
    Localisation : France, Finistère (Bretagne)

    Informations professionnelles :
    Activité : Architecte réseau

    Informations forums :
    Inscription : Janvier 2016
    Messages : 36
    Points : 19
    Points
    19
    Par défaut
    Ok, donc soit je peux me passer de __getattr__ soit je défini __getstate__.

    Je vais creuser un peu les 2 pistes pour voir ce qui est le plus adapté.

    Merci

  6. #6
    Membre à l'essai
    Homme Profil pro
    Architecte réseau
    Inscrit en
    Janvier 2016
    Messages
    36
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 53
    Localisation : France, Finistère (Bretagne)

    Informations professionnelles :
    Activité : Architecte réseau

    Informations forums :
    Inscription : Janvier 2016
    Messages : 36
    Points : 19
    Points
    19
    Par défaut
    Je tourne en rond là-dessus...

    J'ai essayé de ma passer de la méthode __getattr__ dans ma classe SensorSeries , mais cela génère d'autres problèmes avec tkinter lors du pickling...
    Du coup, comme je n'ai besoin en réalité que de sauvegarder les attributs et leurs valeur au moment de la sauvegarde, j'ai essayé de définir la méthode __getstate__ dans ma classe SensorSeries mais là je me perd dans les différentes documentations que je consulte. Je ne comprend pas la marche à suivre pour définir ce qui doit être "pickler" et comment récupérer les infos ensuite.
    J'avais commencé par ajouter cela (dans la définition de ma classe SensorSeries )
    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
    	def __getstate__(self):
    		"""
                    ???
                    :return: ???
                    """
    		self.name
    		self.units
    		self.ymin
    		self.ymax
    		self.color
    		self.marker
    		self.line_style
    		self.marker_size
    		self.line_size
    		self.ylabel
    		self.title
    et dans un premier temps ça "semblait" aller dans le bon sens car l'objet chargé lors du unpickling était semblait être de même nature que celui sauvé, mais en fait l'objet chargé ne possède plus les attributs que je pensais avoir sauvés lors pickling... c'est sans doute plus compliqué que cela à mettre en oeuvre.

    Pouvez-vous me donner un exemple ou une source d'info qui traite de ce sujet de façon... didactique (comprendre les points clés) ?

    Par avance merci pour votre aide

    Pour info je joint le code (http://pasteall.org/951903/python La classe concernée est SensorSeries et les fonctions de sauvegarde et chargement sont save_series_objects et load_series_objects

  7. #7
    Membre confirmé

    Homme Profil pro
    Bidouilleur
    Inscrit en
    Avril 2016
    Messages
    721
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Bidouilleur

    Informations forums :
    Inscription : Avril 2016
    Messages : 721
    Points : 503
    Points
    503
    Billets dans le blog
    1
    Par défaut
    Salut !

    Un get par définition doit retourner quelque chose, là tu retournes rien, enfin si, None.

    En plus pourquoi utiliser ce protocole de pickle ? C'est une obligation due à une particularité quelconque qui m'aurait échappée ?

    Si tu effectuais des tests simples pour déjà comprendre comment ça se passe ?

    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
    import pickle
     
    class Bidule :
        def __init__(self) :
            self.truc = 10
            self.machins = ('a', 'b',)
     
        def __getattr__(self, attr) :
            return self.__dict__[attr]
     
        def __getstate__(self) :
            return self.__dict__
     
        def __setstate__(self, state) :
            print('state', state)
            self.__dict__ = state
     
     
    def sauvegarder(obj) :
        with open('./test_sauvegarde_pickle', 'wb') as f :
            pickle.dump(obj, f, protocol=pickle.HIGHEST_PROTOCOL)
     
    def charger() :
        with open('./test_sauvegarde_pickle', 'rb') as f :
            return pickle.load(f)
     
     
    bid = Bidule()
    print(bid.truc)
    bid.truc = 24
     
    sauvegarder(bid)
     
    bid2 = charger()
    print(type(bid2))
    print(bid2.truc)
    Le temps ronge l'amour comme l'acide.

  8. #8
    Membre à l'essai
    Homme Profil pro
    Architecte réseau
    Inscrit en
    Janvier 2016
    Messages
    36
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 53
    Localisation : France, Finistère (Bretagne)

    Informations professionnelles :
    Activité : Architecte réseau

    Informations forums :
    Inscription : Janvier 2016
    Messages : 36
    Points : 19
    Points
    19
    Par défaut
    Salut !
    Un get par définition doit retourner quelque chose, là tu retournes rien, enfin si, None.
    En effet, ce détail m'avait échappé...

    En plus pourquoi utiliser ce protocole de pickle ? C'est une obligation due à une particularité quelconque qui m'aurait échappée ?
    Je ne sais pas ce que serait une obligation d'utilisation de pickle, mais dans mon cas, cela est supposé me permettre entre chaque session d'utilisation de l'appli, de reprendre là où j'en étais avec les même paramètres. Il sont suffisamment nombreux pour qu'il soit pénible de reparamétrer chaque série une à une... Pickle me semblait être la bonne option.

    Si tu effectuais des tests simples pour déjà comprendre comment ça se passe ?
    Oui, je vais suivre ton conseil et "bistouiller" ton exemple afin de comprendre ce qui se passe...
    Je repasserai ici pour rendre compte de l'état de mon problème.

    Merci

Discussions similaires

  1. Réponses: 5
    Dernier message: 05/05/2017, 08h18
  2. Réponses: 2
    Dernier message: 25/07/2014, 13h27
  3. Sauvegarde des macros en même temps que le classeur
    Par Aureus Magnus dans le forum Macros et VBA Excel
    Réponses: 9
    Dernier message: 11/07/2013, 15h58
  4. Réponses: 4
    Dernier message: 13/06/2007, 09h45
  5. Réponses: 5
    Dernier message: 03/08/2006, 16h13

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo