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?
Réponses
Trop de publicités?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.
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.)
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.
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++
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.