En termes de nouveautés, Python 3.4 est la version de Python qui en apporte le plus ! Il n’y a pas moins de 7 nouveaux modules entre Python 3.4 et 3.3 (séparés de 18 mois), tandis qu’entre Python 3.3 et Python 2.7 (séparés de 27 mois) il y en a huit. En termes de propositions d’améliorations de Python, 14 PEP (Python Enhancement Proposals) ont été implémentées dans Python 3.4. Cette version donne un sérieux coup de vieux à Python 2.7. La 2e partie de la dépêche détaille les principales nouveautés et la manière dont Python est développé.
Mon article Why should OpenStack move to Python 3 right now?, cité ci‐dessous, explique pourquoi Python 2 est désuet et pourquoi vous devez porter dès maintenant vos applications sur Python 3. L’article a été écrit pour le projet OpenStack mais reste général.
Sommaire
-
Nouveautés de Python 3.4
-
7 nouveaux modules
- asyncio : nouveau module de programmation asynchrone, PEP 3156
- ensurepip
- enum : prise en charge des types d’énumération, PEP 435
- pathlib : API orientée objet de manipulation de chemins du système de fichiers, PEP 428
-
selectors : multiplexage d’entrées‐sorties haut niveau et efficace, basé sur les primitives du module
select
, fait parti de la PEP 3156 - statistics : fonctions pour calculer des statistiques mathématiques de données numériques, PEP 450
- tracemalloc : tracer les allocations mémoires de Python, PEP 454
- Nouvelles fonctionnalités
- Améliorations significatives de modules
- Renforcement de la sécurité
- Amélioration de l’implémentation CPython
- Autres changements
-
7 nouveaux modules
- Maturation de Python 3.4
- Python Enhancement Proposals (PEP)
- Petite histoire de la création du module asyncio et du projet Tulip
- Rétroportages
- Pour la suite
Nouveautés de Python 3.4
7 nouveaux modules
asyncio : nouveau module de programmation asynchrone, PEP 3156
Le module asyncio est une boucle d’événements permettant de gérer des événements de types différents dans un unique thread : sockets (TCP, UDP, SSL), signaux UNIX, processus, primitives de synchronisation, etc. Bien que le cœur d’asyncio utilise des callbacks, la programmation se fait essentiellement avec des co‐routines. Une co‐routine est une fonction qui peut être mise en « pause » explicitement avec le mot clé yield
. Pour être précis, asyncio utilise la nouvelle expression yield from
de Python 3.3 qui est plus performante que yield
. Le résultat de la co‐routine est renvoyé par un classique return result
(autre nouveauté de Python 3.3, return
ne pouvait pas être utilisé dans une co‐routine avant). Voici un exemple de « Hello World » asyncio utilisant une co‐routine :
import asyncio
@asyncio.coroutine
def greet_every_two_seconds():
while True:
print('Hello World')
yield from asyncio.sleep(2) # <~~ la magie opère ici
loop = asyncio.get_event_loop()
loop.run_until_complete(greet_every_two_seconds())
Pour vous faire une idée de l’API choisie, je vous conseille de consulter la documentation du module asyncio et notamment les exemples :
- « Hello World » par callbacks ;
- « Hello World » avec des coroutines ;
- écho client en TCP ;
- exemple de processus fils (sous‐processus) ;
- exemple affichant les en‐têtes HTTP de l’URL passée en la ligne de commande.
Pour une présentation plus générale et plus d’information, consultez la liste des conférences sur asyncio.
Pour mon travail chez eNovance, j’ai rétroporté asyncio pour Python 2 dans un nouveau projet appelé Trollius. La raison est que je souhaite remplacer eventlet par Trollius dans le projet OpenStack (en bref : un « petit » projet Python anodin de 2,5 millions de lignes, utilisé dans « le cloud »), en partie pour porter OpenStack sur Python 3. Mon article Use the new asyncio module and Trollius in OpenStack explique tout cela en détails.
ensurepip
Installeur du programme pip
(et de ses dépendances), PEP 453. L’outil pip
devient le gestionnaire de modules de référence pour Python. Le module ensurepip
permet notamment d’installer pip
lors de la création d’un nouvel environnement virtuel avec le module venv
. Lire aussi Rationalizing Python packaging sur LWN.
enum : prise en charge des types d’énumération, PEP 435
Le module enum
fournit une implémentation standard de types énumérés, permettant aux autres modules (tels que socket
) de proposer des messages d’erreur plus explicites, et de faciliter le débogage en remplaçant les constantes opaques avec des valeurs énumérées rétro‐compatibles. Par exemple, print(socket.socket().family)
donne AddressFamily.AF_INET
au lieu de « 2 ».
Ce nouveau module a fait l’objet d’un article An “enum” for Python 3 sur le site LWN.
pathlib : API orientée objet de manipulation de chemins du système de fichiers, PEP 428
selectors : multiplexage d’entrées‐sorties haut niveau et efficace, basé sur les primitives du module select
, fait parti de la PEP 3156
statistics : fonctions pour calculer des statistiques mathématiques de données numériques, PEP 450
tracemalloc : tracer les allocations mémoires de Python, PEP 454
Il existe plusieurs outils pour calculer l’utilisation mémoire d’une application Python, dont notamment Heapy, Pympler et Melia. Le principal défaut de ces outils est qu’ils groupent les allocations selon le type d’objet : quand la majorité de la mémoire est utilisée par des types très courants comme str
ou tuple
, il est très difficile de retrouver la partie du code comportant une fuite de mémoire.
Le nouveau module tracemalloc
prend le problème à l’envers. Plutôt que de partir des objets haut niveau (en parcourant les structures du ramasse‐miettes, module gc
), tracemalloc
se greffe sur l’allocateur mémoire bas niveau pour tracer les allocations mémoire de Python. tracemalloc
utilise ensuite les structures de Python pour reconstituer la pile d’appel où l’allocation a eu lieu et l’associe au bloc mémoire alloué.
Avec ces informations, tracemalloc
permet de :
- fournir la pile d’appel où un objet Python a été alloué ;
- calculer des statistiques par fichier, par numéro de ligne ou par pile d’appel : taille totale, nombre et taille moyenne des blocs alloués ;
- calculer la différence entre deux instantanés (snapshots) pour détecter des fuites mémoires.
L’interface graphique [tracemallocqt](https://bitbucket.org/haypo/tracemallocqt)
permet alors d’analyser finement ces données : filtrage, vue cumulative, groupage des allocations par fichier, ligne ou pile d’appel, comparaison deux instantanés, etc.
Un paquet rétro‐porté est disponible pour Python 2.5-3.3 : pytracemalloc. Il nécessite en revanche l’application d’un correctif, puis de recompiler Python.
Voir aussi la conférence que j’ai donnée à Pycon FR 2013 à Strasbourg sur tracemalloc
: support PDF et enregistrement vidéo. Je donne également une conférence le mois prochain à Pycon Montréal 2014 sur le même sujet.
Nouvelles fonctionnalités
- Les fichiers et sockets nouvellement créés sont marqués comme « non héritables » (PEP 446) : ceci évite de passer des fichiers et sockets aux processus fils, ce qui était la cause de nombreux problèmes et failles de sécurité listés dans la PEP. Ce changement peut casser la compatibilité ascendante, mais c’est un choix pour le bien de l’humanité : « We are aware of the code breakage this is likely to cause, and doing it anyway for the good of mankind. » (extrait de la PEP).
- Nouvelle option en ligne de commande
-I
(isolate) pour lancer Python dans un mode isolé du système. - Amélioration de la gestion des codecs qui ne sont pas des codages de texte (ex :
base64
etrot13
). - Nouveau type
ModuleSpec
pour le système d’importation, PEP 451. - Le format de sérialisation
marshal
est plus compact et plus efficace. - La complétion des commandes par la touche de tabulation est maintenant activée par défaut dans l’interpréteur interactif. Par exemple,
pri<TAB>
est remplacé parprint(
.
Améliorations significatives de modules
-
single‐dispatch générique pour les fonctions dans
functools
, PEP 443 ; - nouveau protocole (quatrième) de sérialisation pour le module
pickle
(PEP 3154) : plus compact et permetant de sérialiser des objets qui ne pouvaient pas l’être avec Python 3.3 ; - le module
multiprocessing
a une nouvelle option pour éviter d’utiliseros.fork()
sous UNIX (voirmultiprocessing.set_start_method()
) ; - le module
email
a un nouveau sous‐modulecontentmanager
et une nouvelle sous‐classe deMessage
(EmailMessage
) qui simplifient la gestion MIME ; - les modules
inspect
etpydoc
sont désormais capables de faire de l’introspection de manière correcte sur une plus grande variété d’objets « callables » (qu’on peut appeler, comme une fonction), ce qui améliore la sortie de la commandehelp()
dans l’interpréteur interactif de Python ; - l’API du module
ipaddress
a été déclarée stable.
Renforcement de la sécurité
- Nouvelle fonction de hachage sûre utilisée par défaut, nommée SipHash (PEP 456), dont on peut lire des détails dans Python adopts SipHash sur LWN ;
- les fichiers et sockets nouvellement créés sont marqués comme « non héritables » (PEP 446) ;
- nouvelle option en ligne de commande
-I
pour lancer Python dans un mode isolé du système ; - le module
multiprocessing
a une nouvelle option pour éviter d’utiliseros.fork()
sous UNIX : les modesspawn
etforkserver
sont plus sûrs, car ils évitent de partager des données avec les processus fils. Sous Windows, les processus fils n’héritent plus de tous les handles héritables du parent, uniquement ceux qui sont nécessaires ; - nouvelle fonction
hashlib.pbkdf2_hmac()
, offrant la 2e fonction de dérivation de clé basée sur un mot de passe de PKCS#5 : PBKDF2 ; - prise en charge des versions 1.1 et 1.2 de TLS par le module
ssl
; - possibilité de récupérer les certificats depuis les dépôts de certificats Windows par le module
ssl
; - le module
ssl
côté serveur gère maintenant SNI (Server Name Indication) ; - la classe
ssl.SSLContext
a été largement améliorée ; - tous les modules de la bibliothèque standard qui gèrent SSL prennent maintenant en compte la validation du certificat serveur, y compris la validation du nom d’hôte (
ssl.match_hostname()
) et la vérification de la listes de révocation de certificats (Certificate Revocation Lists, voirssl.SSLContext.load_verify_locations()
) : ceci veut dire que c’est maintenant possible en écrivant le code approprié, mais la validation demeure désactivée par défaut pour des raisons de compatibilité ascendante et de simplicité d’utilisation (Cf. Python, SSL/TLS certificates and default validation sur LWN).
Amélioration de l’implémentation CPython
-
Safe object finalization (PEP 442) : les objets ayant un destructeur (méthode
__del__
) peuvent maintenant être détruits par le ramasse‐miettes quand ils font partie d’un cycle de référence (ensemble d’objets se référençant entre eux créant un cycle) ; - dans la plupart des cas, les variables globales d’un module ne sont plus mises à
None
à la fin de l’exécution de Python ; - les allocateurs mémoires sont désormais configurables, PEP 445 ;
- The Argument Clinic DSL (PEP 436) offre une introspection complète des fonctions et méthodes implémentées en C. Seule une partie des fonctions C ont été converties vers Argument Clinic, le travail sera terminé dans Python 3.5.
Autres changements
Lisez What’s New in Python 3.4 (lien donné plus haut) pour voir la liste complète des nouveautés et changements de Python 3.4.
Maturation de Python 3.4
La maturation d’une nouvelle version majeure de Python prend de 18 à 20 mois. Pour Python 3.4, le développement a été programmé par la PEP 429 : Python 3.4 Release Schedule. Alors qu’initialement la date de sortie était prévue pour le 22 février 2014, il a été choisi de repousser la sortie pour corriger les bogues majeurs, plutôt que de publier une version boguée.
Le release manager de Python 3.4, Larry Hastings, a eu beaucoup de travail ces deux derniers mois pour canaliser les développeurs et focaliser le développement sur la correction de bogues. Comme d’habitude, l’ajout de nouvelles fonctionnalités était proscrit pendant deux mois dans la branche de développement principale (« default »). Entre la première version release candidate et la version finale, Larry a choisi de créer une branche privée et de choisir quels commits de la branche default
méritaient ou non de faire partie de la future version finale. Ses choix ont été critiqués, mais Larry a tenu bon et a réussi à publier une nouvelle finale !
Python Enhancement Proposals (PEP)
L’ajout d’un nouveau module, les changements touchant au cœur de Python et autres changements majeurs exigent d’écrire une PEP (Python Enhancement Proposal). Ce document sert de support pour discuter les changements et évite notamment qu’une discussion parte dans une boucle infinie (discussion qui repart régulièrement de zéro). Si des variantes sont proposées, elles doivent être notées dans la PEP, et si possible la PEP doit expliquer le choix de la solution proposée.
Une PEP provoque souvent une bonne centaine de messages sur les listes de discussion python-ideas
ou python-dev
, voire plusieurs centaines dans les pires cas. L’auteur de la PEP doit alors tenter d’adresser chaque commentaire et compléter sa PEP au fur et à mesure. Le processus est usant, mais, de mon expérience, l’API après discussion est très largement supérieure à l’API initialement proposée. Discuter une PEP, document de quelques pages, est plus facile que de discuter le correctif de son implémentation (jusqu’à plusieurs milliers de lignes).
Parfois, il y a deux solutions équivalentes qui présentent à peu près les mêmes avantages et inconvénients. Dans ce cas, le BDFL (Benevolent Dictator for Life) (Guido van Rossum) doit trancher entre les deux solutions. Guido van Rossum peut déléguer son rôle s’il n’est pas disponible ou n’est pas intéressé par le sujet.
Pour Python 3.4, les PEP enum
, pathlib
et asyncio
ont provoqué des discussions enflammées avec plusieurs centaines de messages, mais le résultat est là : l’API a été éprouvée. Même si une PEP est refusée, le document en tant que tel devient de facto la référence sur le sujet. Si quelqu’un redemande la même fonctionnalité, la PEP sert d’argumentaire pour expliquer le rejet de la fonctionnalité.
Le processus de rédaction de la PEP garantit également que Python reste un langage cohérent et homogène. D’ailleurs, PHP a adopté un processus similaire depuis PHP 5.3 (PHP: Request for Comments).
Petite histoire de la création du module asyncio et du projet Tulip
Suite à une discussion intitulée « Quelle est la meilleure bibliothèque de programmation asynchrone en Python ? » sur la liste python-ideas
, Guido van Rossum s’est mis dans la tête d’écrire la sienne (bah tiens, tant qu’à faire).
S’en est suivi une discussion fleuve sur les bibliothèques existantes, sur les fonctionnalités attendues d’une telle bibliothèque, sur les callbacks versus co‐routines versus Deferred (Twisted) versus Future, etc. Cette discussion a donné lieu à une PEP 3156 : « Asynchronous IO Support Rebooted: the “asyncio” Module », qui a mis plusieurs mois à être écrite.
Une fois que les bases ont été mises en place, Guido s’est attaqué à une implémentation pour Python 3.3 sous le nom Tulip (le nom du module Python étant asyncio
). Les deux frameworks majeurs étant Twisted et Tornado, il a repris la première lettre « T » et a choisi le nom Tulip : référence à son pays d’origine, les Pays‐Bas ?
La PEP et l’implémentation ont bénéficié de critiques des auteurs des frameworks existants qui ont permis des les améliorer. Les auteurs de Twisted auraient voulu une API plus proche de Twisted, mais Guido a volontairement choisi une API différente, notamment pour la syntaxe des co‐routines.
Rétroportages
Le développement de la plupart des nouveaux modules de Python 3.4 a débuté sur une version plus ancienne de Python. Des rétroportages sont disponibles pour les nouveaux modules :
-
asyncio
,selectors
: trollius pour Python 2.6-3.3 ; -
enum
: enum34 pour Python 2.4-3.3 ; -
pathlib
: pathlib pour Python 2.7-3.3 ; -
statistics
: stats pour Python 3.1-3.3 ; -
tracemalloc
: pytracemalloc pour Python 2.5-3.3.
Pour la suite
Le mois prochain aura lieu Pycon Montréal 2014, rencontre mondiale Python regroupant plusieurs milliers de développeurs. Les nouveautés de Python 3.4 seront présentées, et les prochains développements seront discutés.
J’espère que les efforts sur la programmation asynchrone Python vont se concentrer sur asyncio
, et que de plus en plus de modules vont être compatibles. Il existe des event loops asyncio pour greenlet, gevent, libuv, GLib, Tornado et 0MQ. Il existe des pilotes de base de données pour PostgreSQL, Redis, MongoDB et Memcached. Il existe des clients et serveurs HTTP, Web sockets, et un worker Gunicorn. Voir la page asyncio third party pour la liste complète, certains étant encore expérimentaux.
Bien sûr, l’essentiel des évolutions de Python se fait dans des modules externes. Le dépôt Python PyPI comporte à l’heure actuelle 41 181 paquets.
Aller plus loin
- Python 3.4 (425 clics)
- What’s New In Python 3.4 (406 clics)
- Why should OpenStack move to Python 3 right now? (555 clics)
- LWN: New features in Python 3.4 (94 clics)
- Historique des changements de Python 3.4 (75 clics)
# A quand l'équivalent des symboles Ruby en Python ?
Posté par totof2000 . Évalué à 2.
Ca c'est vraiment un truc qui manque en Python.
[^] # Re: A quand l'équivalent des symboles Ruby en Python ?
Posté par Moonz . Évalué à 2. Dernière modification le 19 mars 2014 à 11:54.
Je ne comprend pas vraiment l’apport relativement à une bête string.
(tu parles bien de
:foo
?)[^] # Re: A quand l'équivalent des symboles Ruby en Python ?
Posté par totof2000 . Évalué à 3.
Je ne le voyais pas non plus avant de le connaitre en Ruby, puis en Erlang avec les atoms qui sont plus ou moins la même chose, mais maintenant que je connais, ça me gène de devoir contourner ce manque avec des strings.
Ca peut éviter par exemple les constructions que tu retrouves en C du style # define TRUC 0 alors qu'il n'y a pas de raison de lui attribuer une valeur. Ca permet également de ne pas à avoir à manipuler des strings alors que ce n'est pas utile. Je vais essayer de retrouver un exemple ou j'ai senti le manque de symbol en python (mais je ne suis pas sur de l'avoir encore sous la main, j'ai changé de mission entre temps).
[^] # Re: A quand l'équivalent des symboles Ruby en Python ?
Posté par reno . Évalué à 4.
Le problème du C c'est que quand tu imprime un enum tu te retrouve avec un entier alors que dans ton programme tu manipules un symbole, c'est pénible a lire ou a gérer pour éviter ça, mais vu qu'avec les enums Python ce n'est pas le cas je ne suis pas sûr que les atom apportent grand chose par rapport aux enum..
[^] # Re: A quand l'équivalent des symboles Ruby en Python ?
Posté par totof2000 . Évalué à 2. Dernière modification le 19 mars 2014 à 15:26.
Qu'est-ce qu'un enum en Python ? c'est ni plus ni moins qu'une structure associative. Pour t'aider à comprendre : suppose qu'en Python tu dois représenter l'état d'une LED : allumé et éteint. Comment fais-tu ?
[^] # Re: A quand l'équivalent des symboles Ruby en Python ?
Posté par reno . Évalué à 2.
Certes et alors?
Je ne comprends pas ta question, ni le rapport avec la "nécessité" d'avoir les symboles en plus des enums "à la Python".
[^] # Re: A quand l'équivalent des symboles Ruby en Python ?
Posté par reno . Évalué à 1.
Certes et alors?Je ne comprends pas ta question, ni le rapport avec la "nécessité" d'avoir les symboles en plus des enums "à la Python".
OK, je viens de voir tes messages suivant et j'ai compris: ton problème est que l'utilisation des enums comme des symboles viole la règle DRY(Don't Repeat Yourself) (enum TOTO='TOTO')
Tu aurais expliqué ça dès le début, ça aurait été plus clair..
Ceci dit, je n'aime pas trop les symboles car ils sont préfixés par :, #, \ (dépend du langage), alors que les enums non..
Tant qu'à rajouter une notation magique pour éviter les répétitions, moi j'aurais fait enum TOTO@ (équivalent de enum TOTO='TOTO') et hop, le moche symbole ne se voit que dans la déclaration de l'enum, est-ce que ça te conviendrait maintenant?
[^] # Re: A quand l'équivalent des symboles Ruby en Python ?
Posté par totof2000 . Évalué à 2. Dernière modification le 19 mars 2014 à 15:52.
Entre autres … :)
Je t'avoue que le symbole est un concept que j'ai eu du mal à comprendre quand j'ai commencé le Ruby, mais qui me parait tellement évident aujourd'hui que j'ai du mal à l'expliquer.
Non parce que tu utilises un objet associatif pour une représentation qui ne l'est pas. L'avantage du symbole est qu'il ne représenter que lui même. Tu n'as pas d'association arbitraire à déclarer nulle part.
En Erlang par exemple, tu différencies l'équivalent du symbole (atom) car il commence en minuscule, contrairement à une variable qui elle commence par une majuscule.
A la limite, tu pourrais je pense utiliser une chaine de caractère là ou on utilise le symbole en ruby, par contre quelque part ça prête à confusion dans le code, vu que le rôle des deux n'est pas tout à fait le même
[^] # Re: A quand l'équivalent des symboles Ruby en Python ?
Posté par totof2000 . Évalué à 2.
Je vais en poser une autre alors: supposons que tu aies un objet représentant une commande de clignotant dans une voiture : ton clignotant peut être dans 3 positions : gauche, droit ou éteint. Comment représenterais-tu celà en Python ?
Peut-être comprendras-tu mieux après.
[^] # Re: A quand l'équivalent des symboles Ruby en Python ?
Posté par Maxime (site web personnel) . Évalué à 5.
Un peu comme en C ?
En Ruby ça donnerait quoi ? Il n'y aurait pas besoin d'enum et possibilité de mettre :gauche, :droit et :eteint ?
Au niveau du typage, ça donnerait quoi ?
[^] # Re: A quand l'équivalent des symboles Ruby en Python ?
Posté par totof2000 . Évalué à 1.
Oui.
Un symbole qui est un type à part entière.
[^] # Re: A quand l'équivalent des symboles Ruby en Python ?
Posté par Antoine . Évalué à 8.
Tous les symboles ont le même type, ce n'est pas la même chose que de définir un type d'énumération distinct par usage.
[^] # Re: A quand l'équivalent des symboles Ruby en Python ?
Posté par Maxime (site web personnel) . Évalué à 4.
En fait, Python supporte les symboles en se limitant à des caractères hexa :D:
Suffirait d'ajouter une nouvelle syntaxe pour exprimer des nombres dans une base 62 (26 * 2 + 10) et ça irait :). Bon, idéalement, on inventerait un nouveau type pour ça quand même.
[^] # Re: A quand l'équivalent des symboles Ruby en Python ?
Posté par GuieA_7 (site web personnel) . Évalué à 3.
Non ça ne marche pas (mais c'était drôle quand même). Il se trouve que dans CPython (mais a priori c'est une question d'implémentation, ce n'est pas portable), les entiers jusqu'à 256 sont des singletons (ils sont pré-alloués en plus me semble-t-il). Chez moi (Python 2.7.6):
Mais
Donc on n'a pas "==" et "is" qui sont équivalents de manière général (et donc pas avec "0xdeadbeef" en particulier).
[^] # Re: A quand l'équivalent des symboles Ruby en Python ?
Posté par Maxime (site web personnel) . Évalué à 2.
Je ne pensais pas à utiliser is en fait, juste ==. Je voyais les symboles comme des int avec des lettres tout simplement. Et donc tout comme avec les int, je n'utilise pas is.
Mais sinon je savais pas pour cette histoire de singletons. J'ai du mal à voir l'intérêt par contre.
[^] # Re: A quand l'équivalent des symboles Ruby en Python ?
Posté par lolop (site web personnel) . Évalué à 2.
C'est un détail interne d'implémentation. Les entiers 0 à 256 (et -1 à -127 je crois) sont très couramment utilisés, et il est plus efficace de les pré-allouer et de ne faire que du comptage de références plutôt que d'allouer/libérer à chaque fois un objet entier correspondant.
Mais c'est vraiment de la cuisine interne, on ne compare jamais deux entiers avec
is
.Votez les 30 juin et 7 juillet, en connaissance de cause. http://www.pointal.net/VotesDeputesRN
[^] # Re: A quand l'équivalent des symboles Ruby en Python ?
Posté par Maxime (site web personnel) . Évalué à 1.
Oui j'avais bien compris mais j'avais oublié un instant que un 'int' n'était pas juste une valeur mais un objet avec des méthodes. D'où l'intérêt d'éviter d'en faire des doublons. Pour la peine, est-ce qu'ils n'auraient pas gagné en perf en faisant une distinction entre int et Integer comme en Java ?
[^] # Re: A quand l'équivalent des symboles Ruby en Python ?
Posté par GuieA_7 (site web personnel) . Évalué à 4.
Ça marche en Java (et C#) grâce au typage statique ; le langage sait s'il faut convertir un
int
enInteger
(ou l'inverse) car il connaît le type des variables et celui des paramètres des méthodes. Mais comment faire en Python ? Ta fonction "def foo(a): […]" comment peut elle savoir si elle reçoit de la part de l'appelant unint
ou un*PyObject
(au sens C) ? Tout repose sur le fait que les variables sont toutes des *PyObjects, et qu'ensuite on applique le duck typing.A noter quand même :
__nonzero__
/__bool__
de "a" n'est pas appelée en cherchant dans la virtual table lorsque Python s'aperçoit que "a" est un*PyInteger
ou une*PyList
par exemple, car en pratique on appelle rarement "if" sur des instances classes utilisateur. Python reste évidemment lent, mais il le serait beaucoup plus s'il était codé naïvement.int
lorsqu'il s'aperçoit que c'est possible et pertinent ; par exemple il va utiliser une version spécialisée de liste si elle ne contient que des*PyInteger
.[^] # Re: A quand l'équivalent des symboles Ruby en Python ?
Posté par xcomcmdr . Évalué à 3. Dernière modification le 19 mars 2014 à 23:36.
Let me Google that for you
TL,DR : ce sont des identifiants. Et ils sont toujours alloués pendant que ton programme tourne, donc c'est à utiliser avec modération.
"Quand certains râlent contre systemd, d'autres s'attaquent aux vrais problèmes." (merci Sinma !)
[^] # Commentaire supprimé
Posté par Anonyme . Évalué à 3.
Ce commentaire a été supprimé par l’équipe de modération.
[^] # Re: A quand l'équivalent des symboles Ruby en Python ?
Posté par Moonz . Évalué à 3. Dernière modification le 19 mars 2014 à 12:03.
C’est en gros une string, notée
:foo
au lieu de"foo"
, avec juste une ou deux différences avec une string normale:Symbol
, pasString
==
impliqueis
)[^] # Re: A quand l'équivalent des symboles Ruby en Python ?
Posté par totof2000 . Évalué à 2.
https://www.ruby-lang.org/fr/documentation/ruby-from-other-languages/
http://fr.wikiversity.org/wiki/Ruby/Symboles
http://www.journaldunet.com/developpeur/tutoriel/ruby/061019-ruby-symboles.shtml
[^] # Re: A quand l'équivalent des symboles Ruby en Python ?
Posté par totof2000 . Évalué à 2.
http://www-etud.iro.umontreal.ca/~dift2035/e2009/cours/introduction_a_ruby_reduite_v0.3.pdf
L'un des intérêts en ruby est qu'on peut appeler des méthodes dynamiquement sans faire appel à Eval : c'est dans un cas de ce genre que ceux-ci m'ont manqués.
[^] # Re: A quand l'équivalent des symboles Ruby en Python ?
Posté par Moonz . Évalué à 4. Dernière modification le 19 mars 2014 à 12:26.
Faisable en Python sans symboles :
[^] # Re: A quand l'équivalent des symboles Ruby en Python ?
Posté par totof2000 . Évalué à 0.
D'après la doc python :
Il semble (mais je peux me tromper) que ceci ne concerne que les attributs et non les méthodes …
[^] # Re: A quand l'équivalent des symboles Ruby en Python ?
Posté par François (site web personnel) . Évalué à 3.
Les méthodes sont des attributs !
[^] # Re: A quand l'équivalent des symboles Ruby en Python ?
Posté par totof2000 . Évalué à 0.
As-tu essayé le code donné plus haut ?
[^] # Re: A quand l'équivalent des symboles Ruby en Python ?
Posté par Moonz . Évalué à 4. Dernière modification le 19 mars 2014 à 13:28.
Pas toi ? :)
François a raison, en Python les méthodes sont des attributs comme les autres. Tu peux même faire des trucs rigolo comme
[^] # Re: A quand l'équivalent des symboles Ruby en Python ?
Posté par totof2000 . Évalué à 1.
Chez moi ça n'a pas marché (voir mon autre commentaire un peu plus haut). Mais je viens de voir que je suis en Python 2.7, pas en Python3. Peut-être pour ça ?
[^] # Re: A quand l'équivalent des symboles Ruby en Python ?
Posté par Moonz . Évalué à 4.
Ça marche aussi sous Python 2.7 pourtant:
[^] # Re: A quand l'équivalent des symboles Ruby en Python ?
Posté par totof2000 . Évalué à 1.
Je viens de réesayer, et ça marche. Je crois que j'ai pris un espace en trop lors du copier/coller. Mais ce que tu fais là me semble bizarre : lorsque j'ai essayer de le transposer à un vrai exemple dans un script (comme celui plus haut), j'ai obtenu une erreur indiquant que l'objet str n'avait pas de méthode foo.
[^] # Re: A quand l'équivalent des symboles Ruby en Python ?
Posté par totof2000 . Évalué à 2.
Bon, j'ai testé, ça marche, mais il y a une ou deux coquilles dans le code fourni à l'origine qui m'ont induit en erreur : le premier paramètre ne doit pas être une chaine :
à l'exécution$ ./toto.py
J'essaierai de retrouver mon exemple car il me semble que c'était un peu plus subtil. Celà dit merci pour l'astuce.
[^] # Re: A quand l'équivalent des symboles Ruby en Python ?
Posté par totof2000 . Évalué à 1. Dernière modification le 19 mars 2014 à 14:35.
Bon, voilà un autre exemple que j'a&i eu à traiter il y a peu :
J'utilise le module logging.
Je veux parser dans 4 fichiers différents les messages de type INFO, WARNING, ERROR, et DEBUG.
Je veux nommer mes fichiers monprog-.log avec "level" correspondant à info, warning, error ou debug.
En ruby, la façon générale de faire est de définir un symbole :ERROR :WARNING :INFO et :DEBUG
J'aurais donc un truc du genre (si les symboles existaient comme en Ruby):
Or actuellement, les levels INFO, WARNING, DEBUG et ERROR soint implémentés ainsi :
ERROR = 40
WARNING = 30
INFO = 20
DEBUG = 10
Comment puis-je donc faire le même genre de chose sans utiliser un dictionnaire ?
[^] # Re: A quand l'équivalent des symboles Ruby en Python ?
Posté par totof2000 . Évalué à 3. Dernière modification le 19 mars 2014 à 14:50.
Je viens d'aller voir le module logger, et comme je le craignais, on a un truc affreux comme ça :
avec plus loin ceci :
Je trouve ça moche et inefficace. Voici donc un exemple précis ou les symboles simplifient la vie et la clarté. Et c'est à cause de ce genre de détails que je préfère Ruby à Python.
[^] # Re: A quand l'équivalent des symboles Ruby en Python ?
Posté par Antoine . Évalué à 1.
L'intérêt c'est d'avoir un ordre bien défini (ERROR est plus grand que WARNING, etc.).
Je ne vois pas le rapport avec les "symboles" Ruby, mais peut-être que quelque chose m'échappe.
[^] # Re: A quand l'équivalent des symboles Ruby en Python ?
Posté par totof2000 . Évalué à 2.
Et pourquoi ? Personnellement, en tant qu'utilisateur de l'API j'en ai rien à faire non ? C'est du détail d'implémentation ça.
En ruby tu définis des symbole ERROR, WARNING INFO et DEBUG. Tu ne leur attribue aucune valeur correspndante : le symbole se suffit à lui même.
[^] # Re: A quand l'équivalent des symboles Ruby en Python ?
Posté par Philippe F (site web personnel) . Évalué à 7.
Dans ce cas, présis, ça a un sens d'avoir un entier associé avec le niveau de log. Tu peux ainsi définir assez facilement la notion de "tous les messages avec un niveau de log supérieur à ERROR" (ERROR + FATAL), "tous les messages avec un niveau de log supérieur à INFO" ( = INFO + WARNING + ERROR + FATAL).
Cela dit, ton besoin d'un symbole abstrait (si je l'ai bien compris) est justement couvert par l'ajout du module Enum à Python 3.4 :
Et tu gagnes en plus une vérification syntaxique à l'assignation de ta variable et non pas à son utilisation…
Pour reprendre ton exemple plus haut en ruby, par exemple, si tu remplaces :WARNING par :WAAAARNING, l'erreur ne sera visible que au niveau du h.setLevel(i) et pas lors de l'énumération des champs possibles.
Si Python utilisais un Enum pour gérer ça, tu aurais un logging.LogLevels = Enum('DEBUG', 'INFO', 'WARNING', 'ERROR' ) et tu pourrais faire :
Mais globalement, si on regarde ça d'un peu plus haut, les différences sont globalement mineures et ne transforment pas massivement ni l'expressivité, ni la fonctionnalité dans un langage ou dans un autre.
Bref, c'est de l'enc******* de mouche .
[^] # Re: A quand l'équivalent des symboles Ruby en Python ?
Posté par Antoine . Évalué à 2.
En Python tu peux faire exactement la même chose avec des chaînes de caractères. Le module logging a fait un choix différent, mais ça ne veut pas dire que ce n'est pas possible.
En d'autres termes, tes récriminations me semblent toujours sans fondement.
[^] # Re: A quand l'équivalent des symboles Ruby en Python ?
Posté par totof2000 . Évalué à 3.
Ce n'est pas la première fois que je rencontre ce genre de cas de figure : avoir un type dédié permet de ne pas se poser de question lorsque tu rencontre une chaine de caractère, savoir si elle est utilisée comme symbole ou comme chaine. A la lecture c'est plus simple à comprendre.
C'est comme beaucoup de choses : on se dit qu'on en a pas besoin tant qu'on ne l'utilise pas, puis quand on se retrouve à l'utiliser on se rend compte après qu'il est difficile de s'en passer.
[^] # Re: A quand l'équivalent des symboles Ruby en Python ?
Posté par Maxime (site web personnel) . Évalué à 5.
Je pense comprendre l'intérêt mais pour moi c'est quelque chose d'assez rare au final. En dehors de considérations de perf, je préfère l'usage d'un enum ou de constantes plutôt qu'un symbole. Pour moi c'est tout aussi clair sauf que si je fais une typo pour mon enum, je devrais avoir une erreur de syntaxe. Comment je peux être sûr avec un symbole ? Déjà que le principal reproche que je fais au python c'est de pouvoir écrire :
au lieu de
sans avoir d'erreur facilement visible. Si en plus on rajoute des symboles qui ne sont pas non plus vérifiables, je repasse au Java.
[^] # Re: A quand l'équivalent des symboles Ruby en Python ?
Posté par Maxime (site web personnel) . Évalué à 3.
Puisque ça manque au Python, est-ce que tu peux donner un exemple concret où la notion de symbole apporterait quelque chose ? N'étant pas familier avec le Ruby, j'ai du mal à voir de quoi il s'agit. J'imagine que c'est différent des types énumérés ?
[^] # Re: A quand l'équivalent des symboles Ruby en Python ?
Posté par Maxime (site web personnel) . Évalué à 3.
Bon, je viens de lire tous les commentaires à ce sujet. Ma conclusion est que ouais ça pourrait être sympa dans de rares cas. Mais franchement, on peut largement s'en passer. On perd encore plus en vérification syntaxique par rapport à un enum ou une constante. Et si on veut un truc qui s'en rapproche, on peut toujours utiliser directement des chaînes de caractère (modulo les perfs peut-être). De toute façon, il y a tellement peu d'exemples où ça change la vie…
[^] # Re: A quand l'équivalent des symboles Ruby en Python ?
Posté par lolop (site web personnel) . Évalué à 7.
Les symboles Ruby sont des chaînes rendues explicitement "intern"—existant de façon unique—via une syntaxe spéciale. En Python l'optimisation faite sur les chaînes courtes litérales réalise la même chose de façon automatique (réutilisation du même objet pour représenter la même chaîne - les chaînes Python étant immutables ça ne pose aucun problème).
Et pour tout ce qui serait issu de saisie ou lecture fichier, un simple appel à
sys.intern()
réalise l'opération.Vérification en utilisant deux modules:
Utilisation des modules.
Votez les 30 juin et 7 juillet, en connaissance de cause. http://www.pointal.net/VotesDeputesRN
[^] # Re: A quand l'équivalent des symboles Ruby en Python ?
Posté par barmic . Évalué à 6.
Après avoir lu tous les commentaires, je trouve que c'est une mauvaise solution à un vrai problème.
Je suis d'accord que l'utilisation des string pour ça est très mauvaise, mais les symboles ne sont pas beaucoup mieux notamment parce qu'ils n'apportent rien en terme de typage et de sécurité.
Tu parle des niveaux de log. Rien ne t'empêche de passer une mauvaise valeur. Tu ne peux pas non plus les énumérer.
Le fait de pouvoir s'en servir pour appeler une méthode me semble aussi affreux.
La bonne solution est simple, c'est une énumération. Celle du C++ est pittoresque, mais si tu regarde du coté de Java par exemple :
Tu peux évidement critiquer la verbosité de java (mais c'est aussi possible en scala, clojure et pleins d'autres). Mais tu as quelque chose qui t'apporte fonctionnellement tout ce que tu cherche avec en plus un typage (ce qui permet de regrouper les valeurs). Bon après en java les enum peuvent en plus porter des données et du code, mais je trouve ça plutôt bien fait.
Les enum de python doivent répondre à ton besoin.
Tous les contenus que j'écris ici sont sous licence CC0 (j'abandonne autant que possible mes droits d'auteur sur mes écrits)
[^] # Re: A quand l'équivalent des symboles Ruby en Python ?
Posté par xcomcmdr . Évalué à 3. Dernière modification le 20 mars 2014 à 22:08.
Euh, c'est rien que de la méta-programmation (on peut aussi utiliser un string à la place), c'est pas cochon, ni interdit par la convention de Genève, je t'assure. ;-)
Pour les symboles, ils sont aussi utilisés dans les hashs (dictionnaire clé/valeur), et parfois quand on veut donner plusieurs arguments à méthode.
"Quand certains râlent contre systemd, d'autres s'attaquent aux vrais problèmes." (merci Sinma !)
[^] # Re: A quand l'équivalent des symboles Ruby en Python ?
Posté par xcomcmdr . Évalué à 2. Dernière modification le 20 mars 2014 à 22:11.
Dans le lien ci-dessous, on utilise les hashs pour les méthodes avec des paramètres optionnels, et pour émuler des méthodes avec des paramètres nommés :
http://ruby.about.com/od/advancedruby/qt/opthash.htm
"Quand certains râlent contre systemd, d'autres s'attaquent aux vrais problèmes." (merci Sinma !)
[^] # Re: A quand l'équivalent des symboles Ruby en Python ?
Posté par lolop (site web personnel) . Évalué à 3.
Pour un nombre variable de paramètres nommés, c'est standard en Python:
Je ne pensais pas que Ruby nécessitait des hacks dans ce genre pour faire des choses aussi triviales.
Votez les 30 juin et 7 juillet, en connaissance de cause. http://www.pointal.net/VotesDeputesRN
[^] # Re: A quand l'équivalent des symboles Ruby en Python ?
Posté par xcomcmdr . Évalué à 2. Dernière modification le 20 mars 2014 à 23:12.
Merci pour l'info sur Python.
Pas mal le trololo à la fin. Mais le "hack" pour Ruby est trivial.
De l'autre côté en Ruby il y a des symboles, les mots clés private/protected/public, les refinements, … ;-)
"Quand certains râlent contre systemd, d'autres s'attaquent aux vrais problèmes." (merci Sinma !)
[^] # Re: A quand l'équivalent des symboles Ruby en Python ?
Posté par lolop (site web personnel) . Évalué à 2.
Appréciable, la page de De Python à Ruby, ça permet de voir les grosses différences. Certaines choses ne sont que syntaxiques, mais d'autres portent sur la sémantique, et là il y a vraiment des choix pour lesquels je préfère ce qui a été fait côté Python:
Sinon, une question, la notation Ruby
:b => 'this great'
dans un appel de fonction, ça crée automatiquement un hash, même sans les accolades?[*] Quoi que, même pour Python, je préférerais presque, entre autre pour mes étudiants, qu'une expression booléenne soit explicite là où on en besoin d'un booléen (if… while…). Le transtypage implicite raccourcit l'écriture mais casse la sémantique.
Votez les 30 juin et 7 juillet, en connaissance de cause. http://www.pointal.net/VotesDeputesRN
[^] # Re: A quand l'équivalent des symboles Ruby en Python ?
Posté par xcomcmdr . Évalué à 2. Dernière modification le 21 mars 2014 à 07:04.
Oui.
Quant aux chaînes mutables, si tu veux un truc non-mutable, les symboles sont là pour ça.
"Quand certains râlent contre systemd, d'autres s'attaquent aux vrais problèmes." (merci Sinma !)
[^] # Re: A quand l'équivalent des symboles Ruby en Python ?
Posté par lolop (site web personnel) . Évalué à 3.
Je veux des chaînes non mutables par défaut, comme le sont les int, bool, float… et str en Python, un bête type de base.
Ne pas avoir à considérer qu'une chaîne est ou pas utile ailleurs, que je peux ou pas la modifier, qu'il y a ou pas des conséquences, qu'il faut penser ou pas à travailler sur une copie.
Chaînes immutables = obligation d'en créer une nouvelle si on veut la modifier, pas d'effet de bord entre les fonctions ou entre les threads.
Votez les 30 juin et 7 juillet, en connaissance de cause. http://www.pointal.net/VotesDeputesRN
[^] # Re: A quand l'équivalent des symboles Ruby en Python ?
Posté par Moonz . Évalué à 2.
Cet argument pourrait s’appliquer à tout objet…
[^] # Re: A quand l'équivalent des symboles Ruby en Python ?
Posté par lolop (site web personnel) . Évalué à 2.
Toutafé, et tu peux définir un objet dont aucune des méthodes ne modifie l'original. Après, on rentre dans d'autres paradigmes de programmation, plus fonctionnelle - mais Python reste pragmatique.
Votez les 30 juin et 7 juillet, en connaissance de cause. http://www.pointal.net/VotesDeputesRN
[^] # Re: A quand l'équivalent des symboles Ruby en Python ?
Posté par lolop (site web personnel) . Évalué à 2.
Q? est-ce qu'il y a une gestion mémoire (ramasse miette, comptage de réfs…) sur les symboles en ruby?
Votez les 30 juin et 7 juillet, en connaissance de cause. http://www.pointal.net/VotesDeputesRN
[^] # Re: A quand l'équivalent des symboles Ruby en Python ?
Posté par djano . Évalué à 3.
Ils comparent avec quelle version de Python?
Les classes old style et new style, ce n'est pas du Python < 3?
[^] # Re: A quand l'équivalent des symboles Ruby en Python ?
Posté par barmic . Évalué à 2.
C'est typiquement tiré de perl ça.
Tous les contenus que j'écris ici sont sous licence CC0 (j'abandonne autant que possible mes droits d'auteur sur mes écrits)
[^] # Re: A quand l'équivalent des symboles Ruby en Python ?
Posté par barmic . Évalué à 4.
Pour la métaprogrammation j'avais mal compris. Pour le reste c'est pas nécessaire ou du moins les enum le permettent avec les avantages que j'ai déjà décris, donc la question ce n'est pas quand est-ce que python aura des symboles, mais quand est-ce que ruby aura des enum si ce n'est pas encore le cas ?
Tous les contenus que j'écris ici sont sous licence CC0 (j'abandonne autant que possible mes droits d'auteur sur mes écrits)
[^] # Re: A quand l'équivalent des symboles Ruby en Python ?
Posté par xcomcmdr . Évalué à 4. Dernière modification le 21 mars 2014 à 07:37.
Cela ne semble pas être à l'ordre du jour, même en consultant les évolutions plus récentes.
Mais en attendant, il y a plusieurs solutions, bien que ma préférée soit celle-ci :
"Quand certains râlent contre systemd, d'autres s'attaquent aux vrais problèmes." (merci Sinma !)
# asyncio vous emmène vers Python 3
Posté par Philippe F (site web personnel) . Évalué à 6.
asyncio, c'est vraiment la killer-feature de cette nouvelle version. Ca pourrait à lui seul justifier que des projets emprisonnés dans Python 2.7 passent en Python 3! Sauf que … il existe un backport Python 2 !
Finalement, presque la totalité des goodies de la lib de Python 3.4 sont disponibles sous forme de backport pour des version inférieures, et notamment Python 2.7 . Et côté évolution du runtime ou du langage, les évolutions ont l'air utiles mais ont relativement peu de chances d'impacter le développeur python "moyen" qui ne pousse pas Python dans ses retranchements. Ah si quand même, les évolutions autour de SSL, va vaut le coup.
[^] # Re: asyncio vous emmène vers Python 3
Posté par Goffi (site web personnel, Mastodon) . Évalué à 4.
C'est pas forcément simple. Nous on est bloqués par Twisted qui est bloqué (entre autres) par une fonctionnalité supprimée de Python 3: http://bugs.python.org/issue3982 . Et le passage à asyncio n'est pas à l'ordre du jour, Twisted a quand même une base de code, outils et protocoles supportés (dont XMPP) qui n'est pas prête d'être rattrapée, le tout étant très testé et stable. Bon ça avance quand même, y'a une partie utilisable en Python 3: http://blog.futurefoundries.com/2014/03/twisted-on-python-3-now-pip-installable.html .
D'un autre côté y'a d'autres projets comme Pyjamas qui ne passeront peut-être jamais à Python 3.
Bref, sans les dépendances, pas facile de songer à passer à Python 3 dans l'immédiat.
[^] # Re: asyncio vous emmène vers Python 3
Posté par Victor STINNER (site web personnel) . Évalué à 5.
asyncio, c'est vraiment la killer-feature de cette nouvelle version. Ca pourrait à lui seul justifier que des projets emprisonnés dans Python 2.7 passent en Python 3! Sauf que … il existe un backport Python 2 !
Trollius n'est pas identique à Tulip. La syntaxe Tulip est plus simple et courante (yield from …/return …) que celle de Trollius (yield From(…)/raise Return(…)) :
http://trollius.readthedocs.org/#differences-between-trollius-and-tulip
Et puis, il manque tellement de choses à Python 2 …
http://haypo-notes.readthedocs.org/python2.html
Bien sûr, il est possible de programmer les bras attachés dans le dos en tapant sur les claviers avec les dents.
[^] # Re: asyncio vous emmène vers Python 3
Posté par Antoine . Évalué à 7.
Ce qui permet, soit dit en passant, d'écrire de l'excellent code Twisted.
[^] # Re: asyncio vous emmène vers Python 3
Posté par Goffi (site web personnel, Mastodon) . Évalué à 2. Dernière modification le 19 mars 2014 à 15:42.
Tu as (vous avez ?) quoi contre Twisted plus précisément ?
[^] # Re: asyncio vous emmène vers Python 3
Posté par Antoine . Évalué à 3.
Personnellement, j'ai quelques raisons de ne pas trop aimer Twisted :
- développeurs opposés à Python 3
- communauté de développement en général assez peu agréable
- architecture un peu byzantine et difficile à comprendre (surtout si l'on veut contribuer des trucs)
- tendance à réinventer la roue
Après, c'est personnel et ça ne reflète pas forcément l'avis des autres core développeurs de Python.
(quant à XMPP, je suis content de savoir que ça marche aujourd'hui, à l'époque où j'avais essayé - vers 2007 -, c'était largement en chantier et le développeur principal n'accueillait pas vraiment les propositions de contribution)
[^] # Re: asyncio vous emmène vers Python 3
Posté par Goffi (site web personnel, Mastodon) . Évalué à 5.
Oki, je comprends mieux
J'ai appris le dernier coup que tu avais tenté un fork python 3, et effectivement ce n'est ouvertement pas dans leur priorités. Maintenant de ce que j'ai compris, ils veulent faire une base de code unique python 2/python 3 et garder la compatibilité ascendante, ce qui vu leur base de code et le nombre de services en production (que j'estime grand sans avoir de chiffre) me parait compréhensible.
Comme indiqué dans mon commentaire plus haut, il y a tout de même une partie de Twisted qui tourne sur Python 3, et pour le reste ils ont l'air bloqué par le bogue mentionné.
Maintenant je suis ça d'assez loin pour le moment, Python 3 n'est pas dans nos priorités non plus, mais la question va se poser de plus en plus, et asyncio n'est pas prêt de rattraper le nombre de protocols supportés par Twisted de sitôt.
Perso je n'ai jamais eu à m'en plaindre, mais j'ai assez peu de contacts avec au final
Ça c'est clair que c'est pas évident à comprendre. Maintenant à l'usage faut reconnaître que ça permet de faire les choses rapidement, j'ai pu lier un serveur IMAP à du XMPP en 1 soir ou 2.
Il y a aussi beaucoup de choses qui étaient là avant (genre ils utilisent le CamelCase parce que la PEP08 a été faite après si je ne m'abuse). Après c'est vrai qu'il y a des choses qu'ils auraient pu réutiliser (logging, test ?), je suppose qu'il y a de bonnes raisons à tout ça.
En dehors de la base dans Twisted, le gros du XMPP est dans Wokkel, qui est une bibliothèque par dessus Twisted et dont le code devrait être mergé à Twisted à terme. C'est encore incomplet, mais y'a de grosses parties implémentées dedans (MUC par exemple), et c'est bien pratique.
Bon en tout cas c'est un peu plus clair, mais même si tu n'aimes pas Twisted, moi c'est un choix que je ne regrette pas: c'est toujours activement développé, c'est très stable (j'ai eu très peu de bogues liés à Twisted/Wokkel jusqu'ici), et c'est puissant. Du coup je trouve ta pique plus haut un peu sévère.
J'espère que Twisted pourra facilement échanger avec asyncio, mais de ce que j'ai compris, les dévs principaux de Twisted et Guido ont longuement discuté ensemble, et c'est justement un des buts affichés.
Bon et sinon bravo pour le boulot général, j'espère ne pas rester éternellement bloqué à Python 2 (y'a aussi Pyjamas qui va poser problème), c'est alléchant tout ça :)
# Deux petites questions
Posté par med . Évalué à 3.
J'ai deux petites questions naïves en attendant que les paquets de python 3.4 arrivent pour ma distribution.
Est-ce que ça veut dire qu'on pourra utiliser le module multiprocessing en appelant une fonction membre d'une classe par exemple ? Pour le moment si je fais un Pool().map(self.member_func, self.args) il me semble que j'ai une erreur à cause de pickle.
Si j'utilise forkserver, est-ce ques les données en mémoire sont copiées pour chaque processus ou bien est-ce qu'on bénéficie encore du copy-on-write comme avec fork() ?
Sinon pour ma part je ne touche plus à python 2. J'ai encore le paquet installé à cause d'une paire de logiciels n'ayant pas encore migré mais c'est bien tout. Je ne saurais plus me passer de python 3. D'ailleurs, est-ce qu'il y a une date en discussion pour la mise à mort officielle de python 2.7 ?
[^] # Re: Deux petites questions
Posté par Antoine . Évalué à 2.
Tout l'intérêt est d'éviter d'hériter des données (et surtout des ressources systèmes : fichiers ouverts, sockets, verrous…) du processus principal, donc la question ne se pose pas : pour passer des données au fils, il faut les sérialiser.
Techniquement, cela fonctionne en lançant un premier processus fils indépendant (le forkserver) qui forkera un fils à chaque demande du processus principal : ainsi chaque fils forké l'est rapidement (fork() est rapide) mais il est entièrement vierge de toute donnée héritée du processus principal (il hérité des données du forkserver, mais il est léger).
[^] # Re: Deux petites questions
Posté par med . Évalué à 4.
Je n'utilise peut-être pas les bon mots, je ne suis pas spécialiste du domaine. Disons que je fais n calculs en parallèle sur un tableau numpy qui peut faire quelques dizaines de Go mais je ne modifie jamais ce tableau. Si je passe naïvement ce tableau ça massacre les performances dans les grandes largeurs, sans parler de l'occupation en mémoire. Donc je cherche à partager ce grand tableau entre les processus. Pour cela je mets les données dans un module tiers que j'importe et par la magie du copy-on-write ça marche bien et vite avec fork(). Le problème est que sur d'autres plateformes ou avec certaines bibliothèques numériques, style OpenBLAS, fork() mène à un deadlock. En théorie forkserver est une solution de ce que j'ai lu¹. Je me demande donc si la méthode de partager des données via un import va fonctionner aussi bien avec forkserver.
¹ https://github.com/obspy/obspy/wiki/Notes-on-Parallel-Processing-with-Python-and-ObsPy
[^] # Re: Deux petites questions
Posté par Victor STINNER (site web personnel) . Évalué à 3.
Il existe différentes méthodes pour partager des données entre plusieurs processus, notamment la mémoire partagée. Dans le cas précis de numpy, je ne sais pas ce qui est le mieux.
J'ai déjà écrit un programme qui partage de la mémoire avec mmap, ça se fait facilement.
[^] # Re: Deux petites questions
Posté par Antoine . Évalué à 2.
Non (de façon délibérée, comme je l'ai expliqué).
[^] # Re: Deux petites questions
Posté par neologix . Évalué à 6.
Atention quand même avec le COW : en effet, tu n'as pas à te tapper la sérialisation.
Mais comme CPython utilise le comptage de référence, le simple accès en "lecture seule" de ce tableau (par exemple juste un itération) va provoquer une duplication des pages, d'où risque de OOM.
[^] # Re: Deux petites questions
Posté par Antoine . Évalué à 2.
Pas avant quelques années, je pense.
# asyncio et socketserver
Posté par matteli . Évalué à 1.
Je profite de cette dépêche pour vous poser une petite question.
Sur un jeu que je développe, j'utilise la class ThreadedTCPServer sur la partie serveur pour communiquer avec un client écrit en C++/Qt (ça marche correctement pour une connexion mais je n'ai pas encore testé la montée en charge).
Ai-je un quelconque avantage à passer au module asyncio ?
Merci
Matt
[^] # Re: asyncio et socketserver
Posté par Victor STINNER (site web personnel) . Évalué à 2.
Utiliser des threads est simple à programmer (si chaque requête n'utilise pas de ressource partagée), mais n'est pas performant pour gérer un grand nombre de requêtes concurrentes. Je m'attends à de meilleures performances avec un grand nombre de requêtes concurrentes (de beaucoup de clients différents).
# Cool !
Posté par flan (site web personnel) . Évalué à 4.
Plein de nouvelles bonnes choses à utiliser ! Bon, je ne pense pas en avoir tout de suite l'utilité (sauf les enum, et à ce propos c'est vrai que les symboles Ruby semblent assez sexy), mais le langage évolue bien, c'est agréable à voir.
L'amélioration de SSL est un grand plus. Par contre, je regrette une chose, c'est les méthodes d'authentification HTTP qui se limitent à Basic et Digest.
Je pensais notamment à Kerberos qui est quand même un peu utilisé, et que je trouve assez difficile à intégrer (notamment sur Windows).
Au passage, le site officiel n'aurait-il pas beaucoup évolué ?
# Justin
Posté par DL . Évalué à 8. Dernière modification le 21 mars 2014 à 15:24.
Juste un commentaire pour dire que je trouve ce journal très intéressant et qui me conforte dans mon choix de rester sur du Python plutôt que céder à apprendre un autre Ruby/Dart/Go/PHP/Perl/…/etc [*] .
Python connait ses dernier temps une progression que je trouve vraiment passionnante, essentiellement dans les domaines des : Maths (Canopy et Pandas n'y sont pas étrangers), Big DAta, et Data mining.
[*] Ces langages ont leur propres intérêts, mais historiquement pour moi ceux que j'ai à mon actif me suffisent, et ce largement grâce à Python, d'où cette reflexion.
[^] # Re: Justin
Posté par Sekigo . Évalué à 6.
J'adore Python, et dès que je peux le caser quelque part (donc, dans à peu près toutes les situations dans mon cas), je le fais.
Mais apprendre d'autres langages, c'est franchement indispensable à mon gout. Ça permet d'apprendre de nouveaux paradigmes, d'aborder des problèmes sous un jour nouveau… et d'apprécier d'autant plus python.
Et parfois, c'est sympa de connaitre un langage un poil plus bas niveau abstraction pour monter en perf (ou pour une partie "critique", ayant fortement besoin de garde-fou niveau prog'). Typiquement du C qui s'interface très bien dans un programme python. Et ainsi, on tape véritablement dans la niche de Python : le script. Un langage qui joue le rôle de chef d'orchestre.
Après, si tu as le temps, je conseille de prendre un langage fonctionnel, type haskell ou ocaml (faudrait d'ailleurs que je prenne le temps de le regarder plus attentivement, celui-ci). C'est fou comme c'est formateur, et comme on devient un meilleur développeur. Sans forcément devenir un killer dans ces technos, juste les aborder est agréable.
[^] # Re: Justin
Posté par DL . Évalué à 2.
Intéressant. Autant je ne suis pas tout à fait ok pour ma liste est trop longue pour dire que je les maîtrise réellement tous; Autant un langage avec un logique d'approche comme ceux que tu cite présente un intérêt pour régler autrement des problèmes que les langages "courants" ne résoudront pas. Et d'ailleurs fan d'IA je me suis penché sérieusement sur LISP dans ce sens.
Mais à la fin, j'ai abandonné car dans mon métier le C et C++ sont la plupart du temps imposés. Et d'ailleurs, si j'ai du aborder d'autres langages (Objective-C, C#, etc) c'est parce que on me le demandait pas par choix.
Du coup il y à une forte différence entre ce que l'on peut faire, et ce que l'on doit faire.
Python sort du lot pour moi car je le préfère largement à la syntaxe de bash, et vu sa versatilité j'ai même l'impression de m'amuser avec.
# Merci
Posté par Gandalf . Évalué à 1.
Merci pour cette dépêche! Sinon une petite question pour les développeurs python : Comment voyez-vous la convergence entre python 2 et 3 ?
Je pense commencer un nouveau projet sous python, et je vais probablement être obligé de partir en 2.7 , les modules que je souhaite utiliser (pyshark et pythonnet) n'étant pas dispo en python 3.
Il y a t-il encore des points de langage bloquants encore la transition des modules vers python 3?
Suivre le flux des commentaires
Note : les commentaires appartiennent à celles et ceux qui les ont postés. Nous n’en sommes pas responsables.