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 :

problème avec __slots__


Sujet :

Python

  1. #1
    Membre émérite
    Homme Profil pro
    Inscrit en
    Décembre 2007
    Messages
    758
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 46
    Localisation : France

    Informations professionnelles :
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Décembre 2007
    Messages : 758
    Par défaut problème avec __slots__
    Bonjour,

    J'ai un problème avec l'utilisation, il y a quelque chose qui m'échappe.

    J'ai testé un exemple trouvé sur un livre (Python en concentré, Alex Martelli, édition O'Reilly 2004 p84-85):

    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
    class Rectangle(object):
        def __init__(self,largeur,hauteur):
            self.largeur = largeur
            self.hauteur = hauteur
        def get_surface(self):
            return self.largeur * self.hauteur
     
    class RectangleOptimise(Rectangle):
        __slots__ = "largeur","hauteur"
     
    r = Rectangle(2.,3.)
    r.surface = r.get_surface()
    print r.surface
     
    r = RectangleOptimise(2.,3.)
    r.surface = r.get_surface()
    print r.surface
    aucune exception n'est levée par le second r.surface = r.get_surface().
    comme si le __slots__ n'avait pas été pris en compte.

    J'ai testé sur 2 versions de l'interpréteur python (2.4.2 et 2.5.4) sur deux machines différentes.

    J'ai remarqué qu'en ajoutant un __slots__ identique à la première classe cela fonctionne comme prévu.

    Vous avez remarqué quelque chose de similaire ?

    Merci d'avance pour votre aide.

  2. #2
    Membre éprouvé
    Inscrit en
    Mars 2003
    Messages
    127
    Détails du profil
    Informations personnelles :
    Âge : 40

    Informations forums :
    Inscription : Mars 2003
    Messages : 127
    Par défaut
    J'ai fais quelque test
    Même cas que toi
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    >>> class C(object):
    ...     def __init__(self,a,b):
    ...        self.s = a + b
    ... 
    >>> class D(C):
    ...     __slots__ = 's'
    ... 
    >>> d = D(2,3)
    >>> d.s
    5
    >>> d.dsd = "dsds"
    Oui mais le slot fonctionne
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    >>> class B(object):
    ...     __slots__ = "s"
    ...     def __init__(self,a,b):
    ...        self.s = a + b
    ... 
    >>> b = B(1,2)
    >>> b.s
    3
    >>> b.sd = "dsd"
    Traceback (most recent call last):
      File "<stdin>", line 1, in <module>
    AttributeError: 'B' object has no attribute 'sd'
    Peut étre à cause de la fonction init bah non ...
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    >>> class G(object):
    ...      pass
    ... 
    >>> class F(G):
    ...     __slots__ = "s"
    ... 
    >>> f = F()
    >>> f.s = "sd"
    >>> f.qsd = "dq"
    Avec cette exemple on comprend que l'attribut slot modifie la classe créé
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    >>> class R(object):
    ...    __slots__ = "ds"
    ... 
    >>> class S(R):
    ...    __slots__ = "d"
    ... 
    >>> s = S()
    >>> s.ds = "dsd"
    >>> s.d = "dd"
    >>> s.dsdqs = "dqsd"
    Traceback (most recent call last):
      File "<stdin>", line 1, in <module>
    AttributeError: 'S' object has no attribute 'dsdqs'
    Il y a même de l'héritage de slot ...

    Donc c'est un peu étrange et d'après ce que j'ai vue il n'est pas conseillé de l'utiliser vous avez une explication ..

    http://docs.python.org/reference/dat...lots#__slots__
    La réponse est la je crois
    When inheriting from a class without __slots__, the __dict__ attribute of that class will always be accessible, so a __slots__ definition in the subclass is meaningless.

  3. #3
    Membre émérite
    Homme Profil pro
    Inscrit en
    Décembre 2007
    Messages
    758
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 46
    Localisation : France

    Informations professionnelles :
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Décembre 2007
    Messages : 758
    Par défaut
    ok merci,

    cela ne vient pas de mon installation python je trouvais ça surprenant.

    ça ne me gêne pas ce type de fonctionnement, ce qui me gênait c'est que j'ai dû y aller à tâtons pour bien comprendre comment ça marchait vraiment (c'est rare avec python compte tenu de la qualité de la doc que l'on trouve partout).

    il se trouve que dans mon projet l'utilisation de __slots__ a un impact colossal sur l'utilisation mémoire, doc je ne suis pas près de le lâcher

  4. #4
    Membre Expert
    Profil pro
    Inscrit en
    Janvier 2007
    Messages
    1 418
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2007
    Messages : 1 418
    Par défaut
    Ayant lu ceci:
    J'ai testé sur 2 versions de l'interpréteur python (2.4.2 et 2.5.4) sur deux machines différentes.
    et étant habitué à chercher dans
    http://www.python.org/doc/2.5.2/lib/genindex.html
    parce que j’utilise la version 2.5,

    j’ai cherché __slots__ dans cet index
    et je ne l’ai pas trouvé.

    L’index de la Library Reference à laquelle on accède à partir de
    http://pys60.garage.maemo.org/doc/
    qui concerne Python 2.5.4
    ne comporte pas non plus __slots__ .



    Par contre, il est bien référencé dans
    http://docs.python.org/glossary.html#term-slots
    qui est la doc de 2.6.2,
    où je lis d’ailleurs:
    __slots__
    A declaration inside a new-style class that saves memory by pre-declaring space for instance attributes and eliminating instance dictionaries. Though popular, the technique is somewhat tricky to get right and is best reserved for rare cases where there are large numbers of instances in a memory-critical application.

    Il me semble donc que __slots__ est une déclaration qui n’apparaît que dans Python 2.6,
    ce qui me conduit à me demander comment kango a-t-il pu faire des essais impliquant __slots__ sous 2.4.2 et 2.5.4 qui ne le comporte pas.





    Par ailleurs, je ne comprends pas ce que vous considérez comme bizarre.
    Je ne suis pas très au courant de ce qui concerne les classes.


    Merci d’éclairer ma lanterne.

  5. #5
    Membre émérite
    Homme Profil pro
    Inscrit en
    Décembre 2007
    Messages
    758
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 46
    Localisation : France

    Informations professionnelles :
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Décembre 2007
    Messages : 758
    Par défaut
    les slots ont été implémentés dans la v2.2:

    http://www.network-theory.co.uk/docs...__slots__.html

    j'étais surpris principalement parce que mon livre (sur la version 2.2 de python) me donnait des infos contraires à ce que j'observais. mais il semble que ce soit des changements intervenus depuis la 2.2

  6. #6
    Membre Expert
    Profil pro
    Inscrit en
    Janvier 2007
    Messages
    1 418
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2007
    Messages : 1 418
    Par défaut
    OK, merci.


    J’ai mal cherché: on retrouve le contenu de ton lien vers le paragraphe 3.4.2.4 du Manuel dans la page suivante
    http://docs.python.org/reference/datamodel.html
    de la doc de 2.6.2 où il est aussi signalé que __slots__ est
    New in version 2.2


    On lit aussi dans la page suivante
    http://docs.python.org/whatsnew/2.2.html :
    PEPs 252 and 253: Type and Class Changes

    The largest and most far-reaching changes in Python 2.2 are to Python’s model of objects and classes. (...)
    Python 2.2 fixes this, and in the process adds some exciting new capabilities. A brief summary:
    - (...)
    - (...)
    - The list of legal attributes for an instance can be limited to a particular set using slots, making it possible to safeguard against typos and perhaps make more optimizations possible in future versions of Python.


    Donc la doc de 2.5 est déficiente sur ce point: on ne trouve pas __slots__ dans son index.



    Y a eu aussi on pov’ gars comme moi qui n’arrivait pas à trouver la doc il y a 4 ans:
    http://www.velocityreviews.com/forum...ots-slots.html





    __slots__ a aussi posé des problèmes à son apparition, si j’en juge par la discussion suivante:
    http://mail.python.org/pipermail/pyt...ry/020076.html

    Je me demande si la discrétion autour de __slots__ pendant un temps ne tenait pas au fait que son usage est délicat et qu’il y avait des bugs.

    Quand tu parles de changements intervenus depuis 2.2, tu dois donc avoir d’autant plus raison qu’on trouve mention de certains changements, apparus avec 2.3 concernant __slots__ , dans la page déjà citée
    http://docs.python.org/reference/datamodel.html

  7. #7
    Membre émérite
    Homme Profil pro
    Inscrit en
    Décembre 2007
    Messages
    758
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 46
    Localisation : France

    Informations professionnelles :
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Décembre 2007
    Messages : 758
    Par défaut
    je considère les __slots__ comme le meilleur outil d'optimisation mémoire des scripts en pur python (c'est à dire sans avoir recours à cython, l'api c de python et autres swig,...)

    voici un petit exemple:

    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
    class Item(object):
        def __init__(self,id=0,name=""):
            self.id = id
            self.name = name
     
    class SlotedItem(object):
        __slots__ = ["id","name"]
        def __init__(self,id=0,name=""):
            self.id = id
            self.name = name
     
    items = []
    for i in xrange(200000):
        items.append(Item(i,str(i)))
    raw_input("done !")

    Avec mon python 2.4.2, environnement Unix:

    97304 ko d'utilisation mémoire avec Item
    39576 ko d'utilisation mémoire avec SlotedItem
    10520 ko d'utilisation mémoire à vide

    Soit 444 o par Item et 149 o par SlotedItem soit grosso modo un rapport de 3.

    De mon expérience avec les __slots__, voici les inconvénients:

    - on perd la souplesse de rajouter des attributs à un objet "sloté"
    - il faut faire attention avec l'héritage (voir post de Tyrus)
    - on ne peut pas faire d'héritage multiple avec des classes ayant des "layout" différents (c'est à dire soit un __slot__ soit un type de base).

    Voir:

    http://groups.google.com/group/comp....2e859b9c002b28
    http://mail.python.org/pipermail/pyt...st/159861.html

  8. #8
    Membre Expert
    Profil pro
    Inscrit en
    Janvier 2007
    Messages
    1 418
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2007
    Messages : 1 418
    Par défaut
    Intéressant tout ça.

    Ce genre de plongée dans les entrailles des classes permet d’approfondir la compréhension des classes, et donc plus généralement des objets “à la Python“. En effet:

    Je dois aussi vous prévenir qu'il y a un piège terminologique pour les lecteurs familiers de l'orienté objet: le mot ``objet'' en Python ne veut pas forcément dire instance d'une classe. Comme en C++ et Modula-3 et contrairement à Smalltalk, tous les types Python ne sont pas des classes: les types intégrés de base comme les entiers et les listes ne le sont pas, et même des types plus exotiques comme les fichiers ne le sont pas non plus. Pourtant, tous les types en Python partagent un peu de sémantique commune, décrite au mieux par le mot objet.
    traduction en français du tutoriel de Guido sur Python 2.0.1 , disponible en html, dont le lien est ici (tout en bas de page):
    http://python.developpez.com/cours/TutoVanRossum/

    Donc, si contrairement à d’autres langages, les classes et instances de classe sont des objets Python, mais ne sont pas les seuls à être des objets Python et qu’il existe d’autres types d’objets, alors toute compréhension approfondie des classes et instances de classe permet de mieux comprendre les arcanes de ce qu’est la notion générale d’un objet en Python.



    Il est à noter que la citation en français ci-dessus ne se trouve plus dans le tutoriel disponible en html sur Python 2.5 , mais en anglais, dont on trouve le lien avec le précédent.

    C’est dommage et c’est bizarre parce que c’est un point particulièrement intéressant me semble-t-il.

    Mais entre la version 2.0 et la version 2.5 de Python, il y a eu la version 2.2 à propos de laquelle A.M.Kuchling a écrit:
    The largest and most far-reaching changes in Python 2.2 are to Python's model of objects and classes.
    http://www.python.org/doc/2.2.2/what...-rellinks.html

    Donc je me méfie, parce que je n’ai pas compris à ce jour plus de 20% de ce qu’est un objet en Python.

    D’ailleurs, si quelqu’un a une référence sur le sujet, cela m’intéresse.









    Par ailleurs, le premier lien que tu donnes, kango,
    http://groups.google.com/group/comp....2e859b9c002b28
    conduit à une page dans laquelle un cadre sur la gauche , en haut, occulte une partie du texte intéressant.
    Dans ce cadre il y a marqué:
    Discussions
    + nouveau message
    À propos de ce groupe

    Abonnement à ce groupe

    Ceci est un groupe Usenet - En savoir plus

    Liens commerciaux
    Logilab
    Spécialiste de Python et du Libre
    pour l'informatique scientifique
    www.logilab.fr
    Python
    Conseils et développements
    Société spécialisée Zope et Plone
    www.zindep.com
    Talend : ETL Open Source
    Solution d'intégration de données
    open source à telecharger
    www.talend.com/download
    Je n’arrive pas a faire disparaître ce cadre.

  9. #9
    Membre éprouvé
    Inscrit en
    Mars 2003
    Messages
    127
    Détails du profil
    Informations personnelles :
    Âge : 40

    Informations forums :
    Inscription : Mars 2003
    Messages : 127
    Par défaut
    Pour avoir une bonne compréhension des objets dans python je conseil de lire ce pdf
    http://www.cafepy.com/article/python...nd_objects.pdf

  10. #10
    Membre émérite
    Homme Profil pro
    Inscrit en
    Décembre 2007
    Messages
    758
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 46
    Localisation : France

    Informations professionnelles :
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Décembre 2007
    Messages : 758
    Par défaut
    en ce qui concerne le lien google groupe, je vois bien l'encadré publicitaire dont tu parles (il est à droite chez moi) mais il ne gêne absolument pas la lecture de la page (je suis sous firefox 3.5.2).

    j'aurais bien du mal à t'expliquer la différence entre l'ancien et le nouveau modèle objet implémenté depuis python 2.2 car il se trouve que le livre auquel je fais allusion plus haut est aussi le livre avec lequel je me suis initié à Python et j'ai toujours pris l'habitude d'utiliser le nouveau modèle objet.

    mais le lien que tu indiques sembles exposer les mêmes choses que dans mon bouquin.

    quant à savoir ce qu'est un objet en python, j'aurais bien envie de répondre que c'est une instance du type PyObject (voir API C de python)

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. VC++ Direct3D8, problème avec LPD3DXFONT et LPD3DTEXTURE8
    Par Magus (Dave) dans le forum DirectX
    Réponses: 3
    Dernier message: 03/08/2002, 11h10
  2. Problème avec [b]struct[/b]
    Par Bouziane Abderraouf dans le forum CORBA
    Réponses: 2
    Dernier message: 17/07/2002, 10h25
  3. Problème avec le type 'Corba::Any_out'
    Par Steven dans le forum CORBA
    Réponses: 2
    Dernier message: 14/07/2002, 18h48
  4. Problème avec la mémoire virtuelle
    Par Anonymous dans le forum CORBA
    Réponses: 13
    Dernier message: 16/04/2002, 16h10

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