33 votes

Pourquoi print statement n'est pas pythonique?

Cette question était sur écoute-moi pendant un certain temps (comme en témoigne ma question précédente): exactement pourquoi est - print(x) de mieux (qui est définie comme étant plus pythonic) que print x?

Pour ceux qui ne le savent pas, l' print déclaration a été changé en fonction en Python 3.0. La documentation officielle est en PEP 3105 et la motivation est dans le Guido van Rossum, l'e-mail.

Sur ces points, je voudrais faire un contrepoint:

  1. Il y a d'autres opérateurs, comme import qui nous écrire comme une déclaration, bien que leur fonctionnalité est en fait dupliqué avec une fonction __import__
  2. Pour les débutants, l'opérateur print n'appartiennent pas à l'application générale de la logique. Pour eux, c'est le mystérieux opérateur qui est le point culminant de leur programme. Ils s'attendent à regarder différemment.
  3. Tous les débutants livres, qui ont été en décrivant de base de Python 2.x sont maintenant garantis à être rompu par le poing par exemple. Certes, les langues parfois des changements, mais les changements sont généralement moins visibles pour les novices.
  4. Il n'est pas immédiatement évident pour moi qu'une fonctionnalité d' print peut être dupliqué au niveau de l'application. Par exemple, parfois je voudrais rediriger l'impression à partir d'une console comme un modal OS dialogue.
  5. Tandis que les gens disent que c'est difficile de réécrire tous print déclarations de fonction, ils ont forcé tous les Python 2.x développeur de faire exactement ce que, pour tous leurs projets. Bon, il n'est pas difficile avec convertisseur automatique.
  6. Tout le monde qui aime avoir une grande capacité à manipuler la fonction print serait tout aussi bien servi si print était une déclaration d'emballage de la fonction __print__.

Ainsi, pouvons-nous avoir une réponse canonique à cette question dans les pages de Débordement de Pile?

57voto

Alex Martelli Points 330805

Me semble que le vôtre est un débat, pas une question, êtes-vous vraiment prêt à accepter une réponse qui montre comment profondément et mal vous étiez dans vos affirmations?!

Sur votre débattre de points:

Il y a d'autres opérateurs, tels que l'importation qui nous écrire comme une déclaration, bien que leur fonctionnalité est en fait en double avec une fonction __import__

Absolument faux: la fonction __import__ (comme tous les autres fonction-et l'opérateur, d'ailleurs) se lie pas les noms dans le champ du "visiteur" (code contenant) -- les "thingie" qui lie les noms dans le "caller " portée" doit être une déclaration (tout comme la cession, def, et call). Votre "point" semble totalement manquer le très profonde et distinction cruciale que Python dessine entre les déclarations et les expressions -- on peut raisonnablement détester cette distinction, mais en ignorant qu'il est, de toute évidence, tout simplement faux.

Des instructions Python sont des choses que l'Python compilateur doit être conscient de -- ils peuvent modifier la liaison de noms, peut altérer le flux de contrôle, et/ou peut-être besoin d'être entièrement supprimé à partir du bytecode généré dans certaines conditions (ce dernier s'applique à l' assert). print a été la seule exception à cette affirmation en Python 2; en le supprimant de la liste des états, Python 3 supprime une exception, fait de l'affirmation générale "il suffit de tenir", et, par conséquent, est plus régulière de la langue. Cas particuliers ne sont pas assez spécial pour briser les règles a longtemps été un Pythonic principe (n' import this à un interactive de l'interprète >>> invite à voir "le Zen de Python" est affiché), et cette modification de la langue supprime une violation de ce principe qui devait rester pendant de nombreuses années en raison d'un début, la conception erronée de la décision.

Pour les débutants, l'opérateur d'impression n' appartiennent pas à la demande générale la logique. Pour eux, c'est le mystérieux l'opérateur qui est le point culminant de leur programme. Ils s'attendent à voir différemment.

Guérir les débutants de leurs préjugés dès que possible est une très bonne chose.

Tous les débutants livres, qui ont été décrivant de base de Python 2.x sont maintenant garanti pour être rompu par le poing exemple. Certes, les langues parfois des changements, mais les changements sont généralement moins visibles pour les novices.

Les langues changent rarement en profondeur et à l'arrière-incompatible moyens (Python est-il environ une fois par décennie) et quelques fonctionnalités de langage sont "très visible pour les novices", de sorte que le nombre total d'observations est petit-pourtant, même au sein de cette minuscule boussole, nous pouvons facilement trouver des contre-exemples, où une fonctionnalité très visible pour les débutants a été tellement mal conçu que le retrait c'était bien la peine de la perturbation. Par exemple, les dialectes modernes de Base, tels que Microsoft Visual Basic, ne pas utiliser explicite de l'utilisateur saisi les numéros de ligne, une "fonction" qui était à la fois terrible et très visible pour absolument tout le monde depuis qu'il a été obligatoire en début de dialectes de Base. Variantes modernes de Lisp (de Régime à partir) n'utilisez pas de dynamique étendue, un misfeature qui a été malheureusement très visible (manifestant habituellement aussi dur à comprendre bugs dans leur code) pour les débutants, en gros dès qu'ils ont commencé à écrire des fonctions Lisp 1.5 (une fois, j'ai été un débutant dans ce et peux témoigner à quel point il m'a mordu).

Il n'est pas immédiatement évident pour moi qu'une fonctionnalité d'impression peut être dupliqué au niveau de l'application. Par exemple, parfois je voudrais redirection d'impression à partir d'une console en tant que modal OS dialogue.

Pas sûr que j'ai suivi ce "point". Il suffit de changer sys.stdout à vos favoris pseudo-fichier de l'objet et de la rediriger vers votre cœur de contenu -- vous avez l' option de monkey patching de la fonction intégrée print (dont vous n'avez jamais eu en Python 2), mais personne n'est à effectuer une torsion du bras et de vous forcer à le faire.

Tandis que les gens disent que c'est difficile de réécrire toutes les instructions d'impression, à une fonction, ils ont forcé tous les Python 2.x développeur de faire exactement cela pour tous de leurs projets. Bon, c'est pas dur avec convertisseur automatique.

L' 2to3 outil, en effet, prendre soin de toutes ces facile de surface incompatibilités -- pas de la sueur (et il doit être exécuté de toute façon de prendre soin de tout à fait un peu de plus en plus d' print,, donc les gens ne les utilisent beaucoup). Alors, quel est votre "point" ici?

Tout le monde qui aime avoir une capacité pour manipuler la fonction d'impression serait tout aussi bien servi si l'impression a été un instruction d'emballage de la fonction d'impression.

Une telle disposition ne serait pas, en soi, de supprimer inutilement un mot-clé (et plus particulièrement erroné de l' irrégularité, comme je l'ai expliqué ci-dessus: une déclaration qui a pas de bonne raison d' être d'une instruction, car il n'y a absolument pas besoin pour le compilateur, être particulièrement conscient de cela, en aucune manière, la forme ou la forme!!!). Il est loin d'être évident pour moi que le fait d'avoir une fonction sous-jacente serait d'ajouter une valeur réelle, mais si vous avez de vrais cas d'utilisation, vous pouvez certainement proposer le cas dans le Python Idées de liste de diffusion -- une fonction sous-jacente, si cela s'avère précieux en effet, pourraient être rénovées pour être utilisé par l' print déclaration en Python 2.7, ainsi que par l' print fonction en Python 3.2.

Cependant, considérons un cas typique dans lequel on peut avoir envie de singe-patch le haut- print: l'ajout de mots clés arguments pour permettre la fantaisie de bricolage. Comment l' __print__ de la fonction vous êtes apparemment proposé jamais ge ceux KW arguments à partir d'une __print__ déclaration? Certains funky encore la syntaxe que les horreurs de la >> myfile et la virgule...?! Avec print comme une fonction, mot-clé arguments suivre parfaitement normal et ordinaire des règles qui s'appliquent pour chaque fonction et la fonction d'appel -- bonheur!

Donc, en résumé, c'est plus Pythonic pour print être une fonction, car elle élimine les anomalies, les cas particuliers, et la nécessité pour bizarre exceptionnelle syntaxe -- la simplicité, la régularité et l'uniformité sont Python de la marque.

11voto

IfLoop Points 59461

Voici la raison pour laquelle je déteste l'instruction print en 2.x.

>>> something()
<something instance at 0xdeadbeef>
>>> print something()
<something instance at 0xdeadbeef>

inutile objet n'est pas utile __str__, Fine, je peux faire face, regardez un peu plus.

>>> dir(something())
['foo', 'bar', 'baz', 'wonderful']
>>> help(something().foo)
"foo(self, callable)"

hmm.. est-ce que l'appelable prendre des arguments?

>>> something().foo(print)
    something().foo(print)
                        ^
SyntaxError: invalid syntax
>>> something().foo(lambda *args: print(*args))
    something().foo(lambda *args: print(*args))
                                      ^
SyntaxError: invalid syntax

Donc... je dois soit de définir une fonction à utiliser

>>> def myPrint(*args): print *args
    def myPrint(*args): print *args
                              ^
SyntaxError: invalid syntax
>>> def myPrint(*args): print args
...
>>> myPrint(1)
(1,)

Frisson, ou utiliser sys.stdout.write, ce qui est presque aussi cludgy, car il est très différent du comportement d' print. Il a également des regards différents, ce qui signifie que je vais presque jamais de rappeler qu'il existe.

À l'aide de print des déclarations dans un court one-off type d'installation et ensuite l'améliorer pour utiliser la journalisation ou quelque chose de mieux, c'est juste inélégante. Si l'impression de l'travaillé comme ces choses, et surtout peut être utilisé avec des fonctions d'ordre, alors il serait mieux que juste la chose que vous utilisez lorsque vous n'utilisez pas de réel de l'exploitation forestière ou réel débogueurs.

8voto

Greg Hewgill Points 356191

La déclaration print contient également la syntaxe inhabituelle >> pour l'impression dans un fichier spécifique. Il n'y a pas d'autre déclaration en Python qui a cette syntaxe, donc c'est inhabituel de cette façon.

Je pense que vous avez raison, la plupart des problèmes liés à l’énoncé print auraient pu être résolus par l’introduction d’une fonction __print__ .

6voto

Jacob Points 33729

J'ai trouvé que "l'impression de GvR est la seule fonctionnalité au niveau de l'application à laquelle une déclaration est dédiée" est convaincante. Python est un langage généraliste et ne devrait pas avoir d'instruction pour exporter un flux en tant qu'opérateur ou mot clé.

3voto

Aiden Bell Points 19856

Il n'est pas pythonic parce que la syntaxe devrait être:

stdout.append("Hello World")

ou

stdout += "hello world"

Avertissement: j'aime Python vraiment.

Sur une note plus sérieuse ...

Je pense que le modèle objet de Python et de mettre en Œuvre vous-même approche des choses comme attribut de visibilité est grande. Je pense que ce "tout est un objet' approche de la programmation orientée objet, et même les objets définis comme une collection d'objets de la structure est très clair à l'esprit.

Ce que je crains Python faire est de devenir une langue qui n'est pas présent, il est des intentions d'une manière claire ... et je n'aimerais pas voir la beauté de l'principes s'enliser dans la pensée déjà la syntaxe non conventionnelle de la présentation. Un peu comme Lisp, belle dans sa structure, sombre, à mon humble avis, dans sa syntaxe.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X