10
votes

Les accesseurs en Python sont-ils jamais justifiés?

Je me rends compte que dans la plupart des cas, c'est préféré dans Python d'accéder directement aux attributs directement, car il n'y a pas de concept réel d'encapsulation comme il n'y a pas de Java et similaire. Cependant, je me demande s'il n'y a aucune exception, en particulier avec des classes abstraites qui ont des implémentations disparates.

Disons que j'écris un tas de classes abstraites (parce que je suis) et qu'ils représentent des choses à voir avec des systèmes de contrôle de la version tels que des référentiels et des révisions (car ils le font). Quelque chose comme une svnrévision et une hGreVision et une gitraVision sont très étroitement sémantiquement liés, et je veux qu'ils puissent faire les mêmes choses (afin que je puisse avoir du code ailleurs qui agit sur n'importe quel type d'objet du référentiel et que l'agnostique de la Sous-classe), c'est pourquoi je veux qu'ils héritent d'une classe abstraite. Cependant, leurs implémentations varient considérablement.

Jusqu'à présent, les sous-classes mises en œuvre partagent beaucoup de noms d'attributs et dans beaucoup de code en dehors des classes elles-mêmes, l'accès à l'attribut direct est utilisé. Par exemple, chaque sous-classe de révision a un attribut d'auteur et un attribut de date, etc. Cependant, les attributs ne sont pas décrits nulle part dans la classe abstraite. Cela me semble comme un design très fragile.

Si quelqu'un veut écrire une autre mise en œuvre de la classe de révision, j'ai l'impression d'être capable de le faire juste en regardant la classe abstraite. Toutefois, une mise en œuvre de la classe qui satisfasse toutes les méthodes abstraites échouera presque certainement, car l'auteur ne saura pas avoir besoin d'attributs appelés «auteur» et de «date», etc., donc le code qui essaie d'accéder à la révision. L'auteur organisera une exception. Probablement pas difficile à trouver la source du problème, mais irritant néanmoins, et cela ressemble à un design inélégant.

Ma solution consistait à écrire des méthodes d'accesseur pour les classes abstraites (get_id, get_author, etc.). Je pensais que c'était en fait une solution assez propre, car elle élimine les restrictions arbitraires sur la manière dont les attributs sont nommés et stockés, et indiquent simplement quelles données l'objet doit pouvoir accéder. Toute classe qui implémente toutes les méthodes de la classe abstraite fonctionnera ... qui se sent bien.

Quoi qu'il en soit, l'équipe que je travaille avec déteste cette solution (apparemment pour la raison pour laquelle les accesseurs sont incessants, que je ne peux pas vraiment discuter avec). Alors ... quelle est l'alternative? Documentation? Ou est le problème que j'imagine un non-problème?

Remarque: j'ai envisagé des propriétés, mais je ne pense pas qu'ils sont une solution plus propre.


10 commentaires

"Il n'y a pas de véritable concept d'encapsulation"? Quoi? J'utilise l'encapsulation tout le temps de mes conceptions.


L'encapsulation est peut-être un terme surchargé. Je l'utilisais comme il fait référence à des informations de cachette. Les premiers points de Google Hits pour "L'encapsulation de Python" étaient le long des lignes de "Python n'ont pas d'encapsulation", alors je me sentais bien de le dire.


Si vous parlez de privé variables, Python a ces. Ils ne sont pas fortement utilisés, cependant, puisqu'ils ne font pas beaucoup de bien. Je ne sais pas quel genre de "cacher" dont vous parlez, vous devriez probablement fournir des liens, des citations et une définition de vos conditions.


Non, ça ne le fait pas. Il a des conventions pour indiquer qu'un attribut est supposé être privé, mais ils ne sont pas appliqués de manière significative. Ils dépendent de la courtoisie. Voir la première partie de cet article pour ce que l'on entend par des informations cachées: en.wikipedia. org / wiki / ...


@Coquelicot: Veuillez définir "de manière significative". Je ne suis pas sûr de ce que vous essayez de faire, mais ce n'est certainement pas clair. Les variables privées sont (bien sûr) visibles à une personne qui lit la source, mais non visible à une personne qui fait une aide () . Qu'est-ce qui est "significatif" pour vous?


@Coquelicot: "Un mécanisme de langue pour limiter l'accès à certains des composants de l'objet." Python a ceci. "Une construction de langue qui facilite le regroupement de données avec les méthodes opérant sur ces données". Python a ceci. Je ne reçois pas quelle distinction vous faites. Ou - peut-être - par "restreindre" vous voulez dire "empêcher"?


Un programmeur qui importe la classe à partir d'un autre module peut inspecter et modifier la valeur des variables «privées» à Python. Ce n'est certainement pas le cas dans des langues comme Java, ou C ++.


@Coquelicot: Est-ce ce dont vous parlez? Restreindre le paramètre d'attribut? S'il vous plaît essayez d'être précis sur cette chose «encapsulation» que vous recherchez.


@ S.Lott Je suis désolé que vous ayez mal compris, mais ces termes sont largement utilisés, et je ne pensais pas à les expliquer. Il semble que vous n'ayez toujours pas tout à fait de votre doigt, mais c'est périphérique à cette question et essayant de le frapper à travers des commentaires est obligé d'être un processus douloureux. Il suffit de regarder dans un livre ou sur Wikipedia ou sur Stackoverflow. Il y a beaucoup de bonnes explications là-bas.


@Coquelicot: "Ces termes sont largement utilisés" et vous demandez des caractéristiques particulières que je ne peux pas comprendre. Je comprends les termes en général. Je ne peux pas comprendre ce que vous signifie quand vous utilise les termes. Je ne peux pas comprendre ce que vous veux.


5 Réponses :


1
votes

2 commentaires

Merci, mais cela ne traite pas vraiment de ma préoccupation (ne pas pouvoir mettre en œuvre la classe abstraite en regardant simplement la définition de la classe elle-même). En outre, il est donc clair, je ne suis pas un programmeur Java (ou C ++ ou autre) essayant de justifier des idiomes Java Shoehorning dans le code Python. J'ai écrit très peu de Java, et je ne suis pas un fan de la langue du tout.


Le fait que l'autre langue dans la vidéo soit Java est sans importance. L'utilisation des accesseurs nécessite directement des modifications du code client, dans toute langue .



1
votes

"Ils devraient pouvoir le faire juste en regardant la classe abstraite"

Je ne sais pas ce que cela devrait être vrai. Un "guide de programmeur", un document "Comment prolonger", plus une formation me semble approprié.

"L'auteur ne saura pas qu'ils ont besoin d'attributs appelés" auteur "et" date "et ainsi de suite".

Dans ce cas, la documentation n'est pas complète. Peut-être que la classe abstraite a besoin d'une meilleure doctorante. Ou un "guide de programmeur", ou un document "Comment prolonger".

En outre, il ne semble pas très difficile de (1) document ces attributs dans la docstring et (2) fournissent des valeurs par défaut dans la méthode __ init __ .

Qu'est-ce qui ne va pas en fournissant un soutien supplémentaire aux programmeurs?

On dirait que vous avez un problème social, pas technique. Code d'écriture pour résoudre un problème social semble être une perte de temps et d'argent.


2 commentaires

Hey, je suis venu ici pour des conseils de programmation. Si je voulais être psychanalysé, j'irais à Freudoverflow. Quoi qu'il en soit, j'aime bien l'idée de mettre la documentation dans le constructeur de la classe de base comme alternative.


@ Coquelicot: Je parle de développement de logiciels bon marché, pragmatique et à faible risque. Écrire plus code pour "résoudre" le problème de quelqu'un d'autre n'est pas un logiciel de haute valeur. Éduquer d'autres développeurs et écrire moins de code réduit les coûts et les risques.



8
votes

Remarque: j'ai envisagé des propriétés, mais je ne pense pas qu'ils sont une solution plus propre. P>

mais ils sont. en utilisant des propriétés, vous aurez la classe Signature que vous souhaitez, tout en pouvant utiliser la propriété comme un attribut lui-même. P>

@property
def id(self):
    return self._id

@id.setter
def id(self, newid):
    self._id = newid

0 commentaires

4
votes

Vous avez manqué le point. Ce n'est pas le manque d'encapsulation qui supprime la nécessité d'accesseurs, c'est le fait que, en passant d'un attribut direct à une propriété, vous pouvez ajouter un accesseur ultérieurement sans modifier l'interface publiée de quelque manière que ce soit.

Dans de nombreuses autres langues, si vous exposez un attribut sous le public, puis souhaitez ensuite envelopper un certain code sur l'accès ou la mutation, vous devez modifier l'interface et que toute personne utilisant le code a à tout le moins de recompiler et éventuellement pour éditer leur code aussi. Python n'est pas comme ça: vous pouvez basculer le flop entre l'attribut ou la propriété autant que vous le souhaitez et qu'aucun code qui utilise la classe ne se casse.


0 commentaires

0
votes

La discussion déjà terminée il y a un an, mais cet extrait semblait révélateur, il convient de discuter:

Cependant, une implémentation de la classe qui satisfait à tous les Les méthodes abstraites seront presque certainement échouer, parce que l'auteur ne saura pas qu'ils ont besoin d'attributs appelés «Auteur» et «date» et ainsi de suite, donc code qui tente d'accéder à la révision.Author va jeter une exception.

euh, quelque chose est profondément mal. (Que dit S. Lott, moins les commentaires personnels). Si ceux-ci sont obligatoires, les membres ne sont-ils pas référencés (sinon requis) dans le constructeur et définis par DOCString? ou à tout le moins, comme requis arguments de méthodes, et à nouveau documenté? Comment les utilisateurs de la classe de la classe pas savent quels sont les membres requis? Pour être l'avocat du diable, que si votre constructeur (s) vous oblige à fournir à tous les membres qui seront requis / peuvent être requis, quel problème cela cause-t-il? En outre, vérifiez-vous les paramètres lors de votre passage et de lancer des exceptions informatives?

(l'argument idéologique de l'accessor-vs-propriété est une barre latérale. Les propriétés sont préférables mais je ne pense pas que ce soit le problème avec votre conception de classe.)


0 commentaires