Pourquoi n'y a-t-il pas de modificateurs d'accès explicites en Python:

28

Si «explicite vaut mieux qu'implicite», pourquoi n'y a-t-il pas de modificateurs d'accès explicites en Python: public, protégé, privé, etc.?

Je sais que l'idée est que le programmeur devrait savoir quoi faire à travers un indice - pas besoin d'utiliser la «force brute». Mais `` l'encapsulation '' ou la `` dissimulation d'informations '' de l'OMI n'est pas seulement pour garder les gens à l'écart, c'est une question d'organisation et de structure: vos couches de développement doivent avoir des étendues et des frontières auto-définies et clairement délimitées, tout comme les systèmes physiques.

Quelqu'un peut-il m'aider s'il vous plaît ici avec une explication solide pour expliquer pourquoi les restrictions d'accès sont implicites plutôt qu'explicites en Python, un langage qui semble autrement proche de la perfection?

Edit: Jusqu'à présent, j'ai vu 3 réponses proposées, et j'ai réalisé qu'il y a 2 parties à ma question:

  1. Pourquoi n'y a-t-il pas de mots clés, par exemple

    private def myFunc(): 
        dostuff....
    

    au lieu de l'OMI, les traits de soulignement laids et difficiles à taper. Mais ce n'est pas le point important.

  2. Plus important:

    Pourquoi ces modificateurs d'accès sont-ils uniquement des «recommandations» ou des conseils et ne sont-ils pas appliqués? Ce sera difficile de changer plus tard? Il est très simple de remplacer «protégé» par «public» - et si vous avez une chaîne d'héritage compliquée qui rend la tâche difficile, votre conception est médiocre - votre conception doit être affinée plutôt que de s'appuyer sur une fonction de langage qui facilite l'écriture. code mal structuré.

    Lorsque les modificateurs d'accès sont appliqués, votre code est automatiquement compartimenté - vous SAVEZ que certains segments sont hors de portée afin que vous n'ayez pas à les traiter sauf si et quand c'est nécessaire. Et, si votre conception n'est pas bonne et que vous vous trouvez constamment à déplacer des choses dans et hors de différents champs, le langage peut vous aider à nettoyer votre acte.

Autant que j'aime Python, je trouve que ce 2e point est une grave lacune. Et je n'ai pas encore vu de bonne réponse à cela.

Vecteur
la source
doublon possible des spécificateurs d'accès en Python: ... qui a été fermé comme n'étant pas constructif.
Frank Shearar
2
@Frank c'est une nouvelle question de cette question pour essayer d'être plus constructif. Je suis allé de l'avant et j'ai supprimé la question d'origine.
@Mark Trapp: Ah OK. Merci pour la clarification. Je ne vois pas comment annuler mon vote de clôture.
Frank Shearar
@Frank Il vieillira tout seul.
Adam Lear
le problème avec private def whatever, c'est class x: def whatever(self): passun raccourci pour class x: pass; x.whatever = lambda self: pass, donc en gros, vous auriez besoin d'un modificateur privé pour l'affectation
keppla

Réponses:

22

"Explicit vaut mieux qu'implicite" n'est qu'une des maximes de la philosophie de conception de Python. "Simple vaut mieux que complexe" est là aussi. Et, bien que ce ne soit pas dans le Zen de Python, "Nous sommes tous des adultes consentants ici" en est un autre.

Cette deuxième règle est peut-être la plus importante ici. Quand je crée une classe, j'ai une idée de la façon dont elle va être utilisée. Mais je ne peux pas prévoir toutes les utilisations possibles. Il se peut que certaines utilisations futures de mon code nécessitent l'accès aux variables que j'ai considérées comme privées. Pourquoi devrais-je rendre difficile, voire impossible, l'accès à ces informations si un futur programmeur (ou même un futur moi) en a besoin? La meilleure chose à faire est de les marquer d'un avertissement - comme le note Joonas, un seul préfixe de soulignement est la norme - qu'ils sont internes et peuvent changer; mais l'interdiction totale de l'accès semble inutile.

Daniel Roseman
la source
1
"Simple vaut mieux que complexe" et "Nous sommes tous des adultes consentants ici", c'est pourquoi Smalltalk n'a pas de modificateurs d'accès. Mettre une méthode dans la catégorie "privée" est un indice que vous devriez penser trois fois avant de l'utiliser, et pas plus.
Frank Shearar
@Frank: "Mettre une méthode dans la catégorie" privée "est un indice que vous devriez penser trois fois avant de l'utiliser, et pas plus" Pour moi, cela signifie simplement que je n'ai pas à m'en soucier quand je n'ai pas affaire avec ça.
Vector
8
Il y a une bonne raison pour laquelle interdire l'accès aux membres privés: car cela peut casser les invariants de classe. Si vous ne pouvez pas écrire de membres privés, vous ne pouvez pas être sûr que votre classe se comporte correctement.
svick
7
"Pourquoi devrais-je rendre difficile, voire impossible, l'accès à ces informations si un futur programmeur (ou même un futur moi) en a besoin?" Parce que l'un des principes de base de la conception est la séparation entre l'interface (ce qu'un code fournit) et l'implémentation (comment il le fournit). L'encapsulation sert à réduire la complexité du code en réduisant les dépendances entre les différentes parties du code. Ainsi, public et privé sont utilisés exactement dans le but de simplifier le code en permettant de voir uniquement ce qui est nécessaire.
Giorgio
3
Je ne peux pas accepter plus. Les modificateurs d'accès promeuvent deux des concepts probablement les mieux compris pour réduire la complexité des gros logiciels: l'encapsulation et la séparation des préoccupations. Ne pas servir aucun des deux signifie simplement que python n'est pas un bon langage de POO ni adapté à la construction de gros logiciels et il n'y a rien de mal à cela. Mais justifiant l'absence de telles fonctionnalités avec des arguments d'amateur typiques comme "Pourquoi ajouter de la complexité quand ce n'est pas nécessaire?" est tout simplement faux.
Daniel Shin
10

Je soupçonne que la principale raison des modificateurs d'accès manquants est la simplicité

Comme vous le dites, il ne s'agit pas de garder les gens à l'écart, c'est une question d'organisation, donc le principal point de «privé» est qu'il envoie un message aux utilisateurs de votre API «veuillez ne pas écrire de code qui dépend de cela».

Il est trivial de dire «par convention, _x ou __x ne devraient pas être utilisés en dehors de la classe», mais dans le modèle d'objet dynamique de python, il serait même difficile de trouver une notation.

class ActiveRow(object):
    def __init__(self, **kwargs):
        for name, value in kwargs.items():
            setattr(self, name, value)

comment noter l'accessibilité?

Je suppose que c'était un compromis. Si vous ne pouvez strictement pas vivre avec, je suggérerais ruby, qui a un niveau d'abstraction et de dynamicité similaire, mais a un modèle d'objet, qui permet la modification de l'accès.

keppla
la source
8
Je pense que c'est correct, mais OMI, c'est terrible. Pour une langue qui utilise l'élégance et la lisibilité comme arguments de vente, l'écriture de __method__ est assez odieuse et obtuse.
jiggy
2
ce n'est pas la convention, __x__sont «magiques» (c'est-à-dire des méthodes qui sont appelées pour permettre l'intégration du langage comme la surcharge des opérateurs, l'itérabilité, etc.). La convention est _x.
keppla
6
Désolé, je suis toujours en train de comprendre Python. J'essaie vraiment de l'aimer, mais des trucs comme ça rendent un peu fou. Surtout maintenant que je dois me souvenir de la signification du nombre de soulignements d'une méthode. Pour OP, il semble que les modificateurs explicites seraient plus clairs. La concision est excellente, mais elle ne peut pas l'emporter sur la clarté. Vous dépensez 10 fois plus d'efforts pour maintenir le code que pour le créer.
jiggy
2
Mon exemple n'était pas censé montrer différents nombres de soulignements, l'utilisation de __init__était accessoire. L'exemple définit certaines propriétés de l'objet, qui ne sont pas connues au moment de la compilation, donc un modificateur d'accès explicite ne vous aiderait pas.
keppla
5
@jiggy: "J'essaie si fort de l'aimer". J'ai essayé pendant 2 ans - puis j'ai abandonné. :-( Semble être un langage de script qui a été piraté pour se comporter un peu comme un vrai langage OOP. Je ne peux pas imaginer écrire une grande application complexe en Python qui était bien conçue et lisible. Comme vous l'avez dit: "Vous dépensez 10 fois plus d'efforts maintenir le code que le construire ". Les concepts simples de POO et de type sûr nécessitent des hacks et des solutions de contournement fous.
Vector
8

La convention Python consiste à utiliser un préfixe de soulignement pour les membres protégés / privés.

Cette convention, lorsqu'elle est suivie, est en fait la même chose que les modificateurs d'accès, sauf 1) vous verrez directement à partir du nom du membre, qu'il soit public ou non, et 2) vous pouvez rompre "l'encapsulation" si vous le voulez vraiment (cela peut être justifié par exemple dans testing; dans certaines autres langues, vous devrez utiliser la réflexion == plus de code).

En fin de compte, c'est une question de goût, mais si vous pouvez faire la même chose (avec un peu plus de flexibilité) sans mots-clés spéciaux, la langue sera plus petite et le code sera plus concis, ce qui est généralement une bonne chose.

Joonas Pulakka
la source
2
"si vous pouvez faire la même chose (avec un peu plus de flexibilité) sans mots-clés spéciaux, la langue sera plus petite et le code sera plus concis" À mon avis, ce n'est généralement pas vrai. (Même si cela peut être vrai avec le cas particulier des modificateurs d'accès)
BenjaminB