web-dev-qa-db-fra.com

Un exemple concret de «une seule façon de le faire» de Python?

J'apprends Python et je suis intrigué par le point suivant de Pep 20 le zen de python:

Il devrait y avoir un-- et de préférence un seul moyen envoûter de le faire. Bien que cette façon ne soit pas évidente au début, sauf si vous êtes néerlandais.

Quelqu'un pourrait-il offrir des exemples concrets de cette maxime? Je suis particulièrement intéressé par le contraste avec d'autres langues telles que Ruby. Partie du Ruby la philosophie de design (originaire de Perl, je pense?) Est-ce que plusieurs façons de le faire est une bonne chose. Peut-on offrir quelques exemples montrant les avantages et les inconvénients de chaque approche. Note, je ne suis pas une réponse à laquelle c'est mieux (ce qui est probablement trop subjectif pour jamais être répondu), mais plutôt une comparaison impartiale des deux styles.

34
Charles Roper

Comparé aux langues comme Perl, Python dispose d'un nombre limité de constructions de contrôle:

  • seulement if et non unless,
  • seulement for qui itière sur des séquences et non foreach ou c-style for,
  • seulement while _ qui vérifie une condition chaque boucle et non do-while,
  • seulement if-Elif et no switch,
  • il n'y a qu'une seule construction de commentaire, le #, et pour chaque ligne que vous pouvez indiquer s'il est commenté ou non, sans regarder les lignes précédentes.

En outre, il y a presque un moyen d'indenter votre source; La plupart des cas d'indentation créative sont syntaxiquement exclus.

Cela fait analyser A Python source plus facile pour les humains.

Il existe des tentatives d'être minimes-mais complètes dans des types intégrés et la bibliothèque standard.

  • pour une liste mutable, vous utilisez le seul type intégré list Type; c'est O(1) pour la plupart des opérations, et vous ne devez jamais choisir la bonne implémentation,
  • pour les listes immuables, également, vous utilisez simplement le type Tuple,
  • pour les cartes, vous utilisez le seul intégré dict qui est agacé efficacement dans la plupart des cas, il n'est pas nécessaire de réfléchir à la mise en œuvre à utiliser.

Python 3 étend ceci aux entiers: peu importe la taille de votre entier, vous utilisez le même type et ne vous souciez jamais de la coercition.

Python essaie d'éviter le sucre syntaxique. Mais parfois Il ajoute du sucre syntaxique juste pour rendre la manière évidente évidente. Vous pouvez écrire if foo is not None Au lieu de if not (foo is None) car "n'est pas" est spécialisé. Toujours foo is not None Se lit facilement, ne peut pas être mal interprété et vous n'avez pas à penser, vous écrivez simplement la chose évidente.

Bien sûr, la plupart des choses plus complexes dans Python canette être effectuée de plusieurs manières. Vous pouvez ajouter des méthodes aux classes par déclaration ou par simple affectation de logement, vous pouvez passer Arguments pour fonctions de plusieurs manières créatives, etc. C'est tout simplement parce que les internes de la langue sont principalement exposés.

La clé est qu'il y a toujours un moyen qui est destiné à être le meilleur, le cas de la couverture. Si d'autres moyens existent, ils n'ont pas été ajoutés comme des alternatives égales (comme if et unless) mais simplement exposer les travaux intérieurs. Lentement mais régulièrement, ces alternatives sont obsolètes (non éliminées!) En améliorant le meilleur mécanisme connu.

Les décorateurs enveloppent les appels de fonction AOP. Avant 2.6, vous avez dû utiliser __metaclass__ Magic Member pour déclarer la métaclasse d'une classe; Maintenant, vous pouvez également utiliser la même syntaxe de décorateur pour cela. Avant 3.0, vous avez eu deux sortes de chaînes, orientées octetiques et unicode, que vous pourriez mélanger par inadvertance. Maintenant, vous avez le seul unicode str et le seul binaire-transparent bytes, que vous ne pouvez pas mélanger par erreur.

47
9000

Un autre couple d'exemples sont:
len() est une fonction au lieu d'une méthode présente dans chaque séquence; Si vous comparez avec Java vous avez .length, .size(), .getSize() et d'autres méthodes pour trouver le nombre d'éléments dans un séquence.

Un autre exemple est le fait que .join() est une méthode string, pas une méthode présente dans chaque séquence. Vous n'avez pas besoin de savoir si le paramètre de jointure est une liste, un ensemble, une compréhension ou autre, cela fonctionnera.

10
Vito De Tullio

En C, il existe de nombreux moyens possibles d'augmenter la valeur d'une variable d'une variable:

i++     // Post-increment, returns the number before the increment
++i     // Pre-increment, returns the number after the increment
i += 1 

Chacun finit par augmenter la valeur de i par 1, mais chacun est légèrement différent.

En Python, il n'y a vraiment qu'un seul moyen; Il suffit d'ajouter un.

i += 1

Et bien qu'il y ait plus d'un moyen de syntaxement valide de le faire (par exemple, i = i + 1), vous faites la même chose avec les mêmes effets secondaires.

8
user32308

Une autre possibilité pourrait être des compréhensions de liste. En python, vous pourrait faire ceci:

new_list = []
    for item in list_of_items:
       if item < 10:
           new_list.append(item)

Mais la méthode "évidente" (si vous êtes néerlandais ou êtes plus familier avec Python) de faire cela serait avec une compréhension de la liste:

new_list = [item for item in list_of_items if item < 10]

C'est plus court, la nouvelle_list est créée en une étape, elle fonctionne plus vite je crois, et c'est élégant. En cas d'inconvénient, on pourrait soutenir que cela se sent moins explicite, mais je pense qu'une fois que vous vous y êtes habitué, c'est tout aussi explicite.

6
Chelonian