Quelles sont les caractéristiques de Python qui le rendent unique en tant que son propre langage? [fermé]


12

Quelles sont les caractéristiques de Python qui le rendent unique en tant que son propre langage? Je recherche toutes sortes de caractéristiques allant du bon au mauvais, utiles à l'encombrement, de la syntaxe à l'utilisation dans le monde réel, mais des observations non obscures seraient les plus utiles pour le développeur moyen.

Je suis un nouveau ici, donc des choses intuitives peuvent devoir être expliquées .....


9
Python n'est pas unique, il ne contient pas une seule fonctionnalité unique qui ne soit vue dans aucun autre langage.
SK-logic

10
C'est la seule langue que je connais qui porte le nom de Monty Python ...
yannis

@ SK-logic, la question porte sur les caractéristiques, dont les caractéristiques sont un sous-ensemble. N'y a-t-il pas de caractéristiques propres à Python?
kojiro

@kojiro, je n'ai jamais vu de définition formelle d'une "caractéristique", donc je préfère ne pas deviner.
SK-logic

1
@kojiro, les fonctionnalités PL sont normalement comprises à la fois comme sa syntaxe et sa sémantique. Et les deux sont formellement définis.
SK-logic

Réponses:


22

Vous aurez du mal à trouver des fonctionnalités absolument uniques . La plupart des fonctionnalités linguistiques existantes ont été adoptées dans plusieurs langues depuis leur création. Certains peuvent être plus rares, principalement parce qu'ils sont nouveaux et toujours dans l'obscurité, ou ont disparu pour une bonne raison. Néanmoins, même alors, vous feriez mieux de regarder des combinaisons de fonctionnalités.

Cela dit, plusieurs fonctionnalités de Python devraient constituer une combinaison relativement unique. Au moins, je ne connais aucune langue à distance aussi populaire (et pratique) avec un ensemble de fonctionnalités qui se chevauchent. Comme indiqué dans les commentaires, Ruby est assez proche, mais il existe néanmoins de nombreuses différences.

  • Métaprogrammation basée sur les métaclasses . Fondamentalement, l'exécution de code arbitraire lors de la création de classes. Permet une personnalisation de classe très agréable avec très peu de travail sur la réception - par exemple pour un mappage relationnel objet (ORM), les classes client peuvent être écrites comme d'habitude avec quelques lignes supplémentaires comme attr = SomeDataType()et une tonne de code est généré automatiquement. Les "modèles" de Django en sont un exemple .
  • Vous êtes encouragé à utiliser des itérateurs pour tout . Cela est particulièrement apparent dans 3.x, où la plupart des alternatives basées sur une liste avec un équivalent basé sur un itérateur ont été supprimées en faveur de ce dernier. Les itérateurs servent également d'interface quasi universelle pour les collections (à la fois celles que vous avez réellement en mémoire et celles dont vous n'avez besoin qu'une seule fois et donc créez avec les fonctionnalités ci-dessous). Indépendant de la collecte, peu encombrant (l' O(1)espace pour les résultats intermédiaires suit souvent naturellement, très peu de tâches nécessitent en fait tous les éléments en mémoire à la fois), la compression des données composables n'a jamais été aussi facile.
  • Expressions de générateur, liées à ce qui précède. Beaucoup auront entendu parler de la compréhension des listes (création d'une liste à partir d'un autre itérable, filtrage et mappage dans le processus, avec une syntaxe très pratique). Oubliez-les, ce sont des sucres syntaxiques, un cas particulier. Les expressions de générateur sont très proches dans la syntaxe et aboutissent finalement à la même séquence d'éléments, mais elles produisent des résultats paresseusement (et prennent donc de l' O(1)espace à moins que vous ne conserviez explicitement les résultats).
  • yield, ce qui rend l'écriture d'itérateurs (appelés ici générateurs) beaucoup plus agréable. Ils sont le grand frère de ce qui précède, soutenant toutes sortes de flux de contrôle. C # a quelque chose de similaire, avec le même mot-clé. Mais il yieldest également surchargé pour prendre en charge un type limité de coroutines (Lua par exemple a un support plus élaboré) qui a néanmoins été mis à profit par des personnes intelligentes travaillant sur des problèmes difficiles. Deux exemples sur le dessus de ma tête: analyse récursive de descente avec backtracing et aucune limite de pile et E / S asynchrones (avec une syntaxe pratique).
  • Affectation multi-cibles et déballage itérable. Affectation sur les stéroïdes. Non seulement vous pouvez attribuer plusieurs valeurs à la fois (même pour échanger des valeurs et lors de l'itération - for key, value in mapping.items()), vous pouvez décompresser tout itérable de longueur connue (honnêtement, principalement des tuples) en plusieurs variables. Depuis 3.x , il est même pratique pour les collections de longueur inconnue que vous pouvez spécifier quelques variables prenant simples éléments et une prise ce qui reste: first, *everything_in_between, last = values.
  • Descripteurs , probablement les plus puissants parmi les différentes façons de personnaliser l'accès aux attributs. Il existe des propriétés (comme en C #, mais sans support de langage spécial), des méthodes statiques, des méthodes de classe, etc. toutes implémentées en tant que descripteurs. Ce sont également des objets de première classe. Il y a à peine une semaine, j'ai été confronté à du code répétitif et délicat dans les propriétés - j'ai donc écrit une petite fonction générant la partie répétitive et l'enveloppant dans un properyobjet.
  • Règle purement hors-jeu (indentaion pour délimiter les blocs). J'ai mis ce dernier intentionnellement. Bien qu'il distingue Python, il ne se démarque pas vraiment dans la programmation quotidienne une fois que vous y êtes habitué (ou du moins c'est mon expérience).

Je suis encore un peu nouveau chez Ruby mais je pense que ça touche tout sauf le dernier point? Quoi qu'il en soit, je suis d'accord pour dire que "unique" ne sera probablement pas trouvé en Python mais "pas commun parmi les autres langages" peut l'être.
Rig

@Rig: Je ne suis pas un expert Ruby, mais je n'ai vu ni métaclasses (Ruby est certainement aussi puissante en ce qui concerne la métaprogrammation, et je peux l'utiliser à des fins similaires, mais j'ai l'impression que c'est réalisé différemment), ni générateurs ni expressions de générateur (bien qu'il semble y avoir des coroutines), ni un déballage itérable (il y a cependant une affectation multi-cible) ni des descripteurs dans Ruby. Oui, Ruby et Python se chevauchent. Mais il y a des différences .

Bon, +1. Pour moi, "l'affectation sur les stéroïdes" est en fait "la correspondance de motifs du pauvre", mais elle est néanmoins incroyablement utile :) Je remarquerais également à quel point le passage des paramètres dans les fonctions est flexible: *argset **kwargs, moyen indolore de mapper les tuples et les dict aux paramètres, etc. .
9000

Je crois que le lisp commun avec CLOS touche tous les points sauf l'utilisation de la syntaxe basée sur la mise en page. Haskell n'est pas orienté objet (bien qu'il existe des extensions OO) mais à part le point de métaclasse, je pense qu'il correspond à toutes ces fonctionnalités.
Jules

3

Je suppose que la seule chose qui rend Python unique est la combinaison particulière de fonctionnalités qu'il expose. Cela serait vrai pour la plupart des langages de programmation.

Ou il peut y avoir une petite chose: je n'ai pas vu la façon dont Python passe explicitement en selftant que paramètre formel aux fonctions membres d'objet effectuées dans un autre langage. C'est une petite chose, et je ne vois pas vraiment comment cela change quoi que ce soit.

Mais je ne parle pas très bien Python, donc il y a peut-être des choses qui me manquent à coup sûr!


@delnan: Ah, j'ai raté "passer explicitement le moi comme paramètre formel" .. Je suppose que c'est ce que j'obtiens en lisant à 2h du matin;)
Demian Brecht

4
Le moi explicite se produit également à Oberon, fwiw
grrussel

Un paramètre auto explicite est également utilisé dans le système d'objets lisp commun. CLOS fournit cependant plusieurs méthodes, ce qui signifie que le paramètre self n'est en rien spécial, comme c'est le cas en python.
Jules

1

Le traitement automatique des docstrings pour devenir les propriétés de leur propriétaire. En général, toutes les brillantes fonctionnalités d'introspection de Python en font un langage très unique, de la capacité à utiliser help () à la capacité à utiliser __doc__comme propriété de première classe d'un objet. Par exemple:

>>> class DocStringException(Exception):
...     """Error message is the same as docstring"""
...     def __str__(self):
...         return repr(self.__doc__)
... 
>>> class ExampleException(DocStringException):
...     """An example happened"""
... 
>>> raise ExampleException
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
__main__.ExampleException: 'An example happened'

Autres fonctionnalités d'introspection utiles:

  • help / help () - aide avec l'interpréteur / aide avec un objet
  • mots-clés - mots-clés python
  • locals () - récupère les noms locaux
  • globals () - récupère les noms globaux
  • dir () - récupère les propriétés et méthodes d'un objet
  • la méthode .mro. , issubclass - comprendre l'héritage
  • id () - récupère l'adresse mémoire d'un objet

Ruby a à peu près le même pouvoir, tout comme Common Lisp, Clojure et de nombreux autres langages dynamiques je crois.
Torbjørn

@ Torbjørn quelle puissance? La documentation automatique ou les fonctionnalités d'introspection?
kojiro

Je pensais aux deux. Pas exactement le mot à dire, mais dans l'esprit. Je ne crois pas que Ruby ait les mêmes capacités de documentation, mais l'introspection à coup sûr. CL et Clojure ont les deux fonctionnalités - et je pense que l'introspection là-bas va bien au-delà de ce que vous trouverez en Python, car il est homoiconique .
Torbjørn du

1
  1. Generator Expressions
  2. input()Laissez-moi vous expliquer, je n'ai pas vu de langage (jusqu'à présent), où vous pouvez attribuer une valeur à une instruction qui imprime quelque chose, c'est comme Ruby print/gets, mais avec une valeur affectée à l'impression, au lieu de:print "Foo" bar = gets
  3. yield
  4. De nombreux types d'ensembles de données: ordereddict, namedtuple, array, list, tuple, dictionary

Les expressions de générateur peuvent être implémentées dans Haskell en utilisant des compréhensions de liste (les listes Haskell sont paresseuses, contrairement aux listes python, donc aucune syntaxe spécifique n'est nécessaire pour cela). Par "entrée", je suppose que vous entendez la fonction python 3 de ce nom (car la fonction python 2 est dangereuse et ne doit pas être utilisée). Il est vrai que c'est une combinaison inhabituelle de comportement (bien qu'il soit présent dans javascript - window.prompt - et BASIC, où je suppose que python l'a emprunté) mais il peut être mis en œuvre trivialement par le programmeur ("input s = putStrLn s >> getStrLn "le fera pour haskell).
Jules

Un langage paresseux comme Haskell n'a pas vraiment besoin de rendement - il peut simplement renvoyer une liste établie à l'aide des méthodes habituelles, et les éléments seront générés à la demande. Malgré cela, la bibliothèque inclut une implémentation explicite des coroutines. La bibliothèque standard Haskell contient toutes les structures de données mentionnées, et bien d'autres.
Jules

-2

Le fait est que Python est parmi très peu de langages avec une surcharge syntaxique extrêmement faible, ce qui lui confère d'énormes pouvoirs expressifs: compréhension de liste / ensemble / dict, rendement, décorateurs, eval, programmation de méta-classe, introspection, les structures de données intégrées optimisées (listes, dits, sets), toutes ces choses conspirent d'une manière très agréable pour vous donner (au développeur) le pouvoir d'exprimer vos pensées dans un code concis et élégant presque aussi vite que vous pouvez le penser. Je ne peux pas vraiment penser à d'autres langues avec cet ensemble de fonctionnalités killer combiné.


1
Si vous pensez que Python a une surcharge syntaxique faible (malgré une grammaire obscurément compliquée et une quantité relativement importante de sucre syntaxique), que pensez-vous de Scheme?
Tikhon Jelvis

Eval ne devrait vraiment pas être utilisé pour aucun programme de production (bien que j'accorde qu'il puisse être pratique pour des hacks rapides). Comme indiqué dans les commentaires pour d'autres questions, python n'est en aucun cas unique en ce qui concerne ces fonctionnalités. Je crois, par exemple, que clojure possède toutes les fonctionnalités que vous énumérez, et la plupart peuvent être effectuées avec lisp commun.
Jules

-4

Je dirais que c'est l'utilisation de l'indentation pour joindre des instructions et des boucles. Je n'ai vu cela dans aucune autre langue.

Je pense que c'est très pratique car cela rend beaucoup plus difficile d'obscurcir le code python!

Il semble également s'exécuter de manière ordonnée ligne par ligne à l'exception des fonctions, et il peut également être interprété comme tel, ce qui est bien.


2
Wikipedia connaît un écran plein de langues qui le font aussi. Cela s'appelle la règle du hors-jeu .

3
Je ne comprends pas Il semble également s'exécuter de manière ordonnée ligne par ligne à l'exception des fonctions, et il peut également être interprété comme tel, ce qui est bien. Qu'est-ce que ça veut dire?
kojiro
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.