107 votes

Quel est le but des classes internes de python?

Les classes internes / imbriquées de Python me déroutent. Y a-t-il quelque chose qui ne peut être accompli sans eux? Si oui, quelle est cette chose?

93voto

Aziz Points 7500

Cité de http://www.geekinterview.com/question_details/64739:

Avantages de l'intérieur de la classe:

  • Regroupement logique des classes: Si une classe est utile à une seule autre classe, alors il est logique de les intégrer dans la classe et garder les deux ensemble. L'imbrication de ces "classes d'aide" rend leur package de plus simple.
  • Augmentation de l'encapsulation: Considérons deux classes de haut niveau A et B, où B a besoin d'accéder aux membres d'Un qui serait par ailleurs déclaré privé. En se cachant de catégorie B au sein de la classe Un Un des membres peut être déclaré en privé et B peuvent y accéder. En outre B lui-même peut être caché du monde extérieur.
  • Plus lisible, maintenable code: Imbrication des petites classes dans les classes de niveau supérieur lieux le code de plus près à l'endroit où il est utilisé.

Le principal avantage est l'organisation. Tout ce qui peut être accompli à l'intérieur des classes peut se faire sans eux.

52voto

bobince Points 270740

Est-il quelque chose qui ne peut être accompli sans eux?

Pas de. Ils sont absolument équivalent à la définition de la classe normalement au plus haut niveau, et puis de copier une référence vers l'extérieur de la classe.

Je ne pense pas qu'il y a une raison particulière classes imbriquées sont "autorisés", les autres qu'il ne fait pas de sens particulier explicitement ‘interdire'.

Si vous êtes à la recherche pour une classe qui existe dans le cycle de vie de l'extérieur/propriétaire de l'objet, et a toujours une référence à une instance de l'extérieur de la classe interne des classes Java – Python classes imbriquées ne sont pas de cette chose. Mais vous pouvez pirater quelque chose comme cette chose:

import weakref, new

class innerclass(object):
    """Descriptor for making inner classes.

    Adds a property 'owner' to the inner class, pointing to the outer
    owner instance.
    """

    # Use a weakref dict to memoise previous results so that
    # instance.Inner() always returns the same inner classobj.
    #
    def __init__(self, inner):
        self.inner= inner
        self.instances= weakref.WeakKeyDictionary()

    # Not thread-safe - consider adding a lock.
    #
    def __get__(self, instance, _):
        if instance is None:
            return self.inner
        if instance not in self.instances:
            self.instances[instance]= new.classobj(
                self.inner.__name__, (self.inner,), {'owner': instance}
            )
        return self.instances[instance]


# Using an inner class
#
class Outer(object):
    @innerclass
    class Inner(object):
        def __repr__(self):
            return '<%s.%s inner object of %r>' % (
                self.owner.__class__.__name__,
                self.__class__.__name__,
                self.owner
            )

>>> o1= Outer()
>>> o2= Outer()
>>> i1= o1.Inner()
>>> i1
<Outer.Inner inner object of <__main__.Outer object at 0x7fb2cd62de90>>
>>> isinstance(i1, Outer.Inner)
True
>>> isinstance(i1, o1.Inner)
True
>>> isinstance(i1, o2.Inner)
False

(Cela utilise la classe décorateurs, qui sont de nouveau en Python 2.6 et 3.0. Sinon, vous auriez à dire "Intérieure= innerclass(Interne)" après la définition de la classe.)

37voto

Jason Baker Points 56682

Il y a quelque chose que vous devez enrouler autour de votre tête pour être en mesure de comprendre cela. Dans la plupart des langues, des définitions de classe sont les directives du compilateur. C'est-à-dire, la classe est créée avant que le programme est exécuté. En python, toutes les déclarations sont exécutables. Cela signifie que cette déclaration:

class foo(object):
    pass

est une instruction qui est exécutée lors de l'exécution, tout comme celui-ci:

x = y + z

Cela signifie que non seulement vous pouvez créer des classes dans d'autres classes, vous pouvez créer des classes n'importe où vous voulez. Considérer ce code:

def foo():
    class bar(object):
        ...
    z = bar()

Ainsi, l'idée d'un "intérieure" n'est pas vraiment une langue de construire, il est un programmeur de construire. Guido est un très bon résumé de la façon dont cela s'est fait ici. Mais, pour l'essentiel, l'idée de base est cela simplifie la grammaire d'une langue.

15voto

Ed. Points 299

L'imbrication des classes dans les classes:

  • Classes imbriquées gonfler la définition de classe, ce qui rend plus difficile de voir ce qui se passe.

  • Classes imbriquées peuvent créer de couplage qui permettrait de rendre le test plus difficile.

  • En Python, vous pouvez mettre plus d'une classe dans un fichier/module, contrairement à Java, de sorte que la classe reste toujours proche de classe de haut niveau et pourrait même avoir le nom de la classe précédé d'un "_" pour l'aider à indiquer que d'autres ne devraient pas l'utiliser.

L'endroit où les classes imbriquées peut s'avérer utile dans les fonctions

def some_func(a, b, c):
   class SomeClass(a):
      def some_method(self):
         return b
   SomeClass.__doc__ = c
   return SomeClass

La classe capture les valeurs de la fonction vous permettant de créer dynamiquement une classe comme modèle de la métaprogrammation en C++

7voto

user411279 Points 415

Je comprends les arguments contre les classes imbriquées, mais il y a un cas d'utilisation dans certaines occasions. Imagine que je suis la création d'une liste à double liaison de la classe, et j'ai besoin de créer une classe de nœud pour maintenant les nœuds. J'ai deux choix, créer de la classe de Nœud à l'intérieur de la DoublyLinkedList classe, ou la création de la classe de Nœud à l'extérieur de la DoublyLinkedList classe. Je préfère le premier choix dans ce cas, parce que le Nœud est la classe n'a de sens qu'à l'intérieur de la DoublyLinkedList classe. Alors il n'y a pas de cacher/encapsulation des avantages, il y a un regroupement avantage d'être en mesure de dire à la classe de Nœud fait partie de la DoublyLinkedList classe.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X