Code Python2.x vers Python3.x

Le
Nicolas
Bonjour,

Soit, le code suivant :
self.records = [r for r in self.records if r[self.key]<other]

Avec Python2.x, si self.key et other sont de type différents, la
comparaison retourne True ou False en fonction des types.
Avec Python3.x, ce n'est pas permis. Une exception est retournée.

Mon code modifié pour Python 3.x est :
rec = []
for r in self.records :
try :
if r[self.key]<other :
rec.append(r)
except TypeError :
pass
self.records = rec

Y a t-il une écriture plus concise possible ?

Nicolas
Vidéos High-Tech et Jeu Vidéo
Téléchargements
Vos réponses Page 1 / 2
Gagnez chaque mois un abonnement Premium avec GNT : Inscrivez-vous !
Trier par : date / pertinence
Pierre Maurette
Le #23845751
Nicolas :
Bonjour,

Soit, le code suivant :
self.records = [r for r in self.records if r[self.key]<other]

Avec Python2.x, si self.key et other sont de type différents, la comparaison
retourne True ou False en fonction des types.
Avec Python3.x, ce n'est pas permis. Une exception est retournée.

Mon code modifié pour Python 3.x est :
rec = []
for r in self.records :
try :
if r[self.key]<other :
rec.append(r)
except TypeError :
pass
self.records = rec

Y a t-il une écriture plus concise possible ?



Je n'ai pas encore pratiqué Python3.x. Vous devriez pouvoir conserver
une écriture en une ligne avec:
(type(a) is type(b)) and (a < b) #parenthèses surnuméraires volontaires

A adapter à la logique souhaitée en utilisant:

- les règles d'évaluation paresseuse des expressions logiques:
A and B, B n'est pas évaluée si A vaut False
A or B, B n'est pas évaluée si A vaut True

- De Morgan: !(A and B) = (!A or !B) et équivalents.

Enfin, c'est ce que je ferais pour aller vite, mais il se trouve que je
/lis/ facilement ce type d'expression, alors que certains trouvent ça
illisible. Attention toutefois, type(a) is type(b) renvoie False pour
deux types numériques comparables mais différents (2 et 2.6 par
exemple), ça se corrige également, mais ça commence à alourdir.
Peut-être y a-t-il beaucoup plus simple ?

--
Pierre Maurette
Alain Ketterlin
Le #23845741
Nicolas
Soit, le code suivant :
self.records = [r for r in self.records if r[self.key]<other]

Avec Python2.x, si self.key et other sont de type différents, la
comparaison retourne True ou False en fonction des types.
Avec Python3.x, ce n'est pas permis. Une exception est retournée.

Mon code modifié pour Python 3.x est :
rec = []
for r in self.records :
try :
if r[self.key]<other :
rec.append(r)
except TypeError :
pass
self.records = rec

Y a t-il une écriture plus concise possible ?



En utilisant type() ?

-- Alain.
Nicolas
Le #23846181
Le 10/10/2011 15:10, Alain Ketterlin a écrit :
Nicolas
Soit, le code suivant :
self.records = [r for r in self.records if r[self.key]<other]

Avec Python2.x, si self.key et other sont de type différents, la
comparaison retourne True ou False en fonction des types.
Avec Python3.x, ce n'est pas permis. Une exception est retournée.

Mon code modifié pour Python 3.x est :
rec = []
for r in self.records :
try :
if r[self.key]<other :
rec.append(r)
except TypeError :
pass
self.records = rec

Y a t-il une écriture plus concise possible ?



En utilisant type() ?

-- Alain.


Je n'avais pas pensé à valider les arguments avant le test.
Merci Pierre et Alain.

Nicolas
Nicolas
Le #23855821
Le 10/10/2011 16:53, Nicolas a écrit :
Le 10/10/2011 15:10, Alain Ketterlin a écrit :
Nicolas
Soit, le code suivant :
self.records = [r for r in self.records if r[self.key]<other]

Avec Python2.x, si self.key et other sont de type différents, la
comparaison retourne True ou False en fonction des types.
Avec Python3.x, ce n'est pas permis. Une exception est retournée.

Mon code modifié pour Python 3.x est :
rec = []
for r in self.records :
try :
if r[self.key]<other :
rec.append(r)
except TypeError :
pass
self.records = rec

Y a t-il une écriture plus concise possible ?



En utilisant type() ?

-- Alain.


Je n'avais pas pensé à valider les arguments avant le test.
Merci Pierre et Alain.

Nicolas


Après quelques essais, je vais garder la forme développée avec un
try/except. La validation des arguments est trop restrictive.
Par exemple, la comparaison d'un entier et d'un flottant est autorisée.
Alors que type(int) et type(float) sont différents.

Nicolas
Laurent Pointal
Le #23863901
Nicolas wrote:

Le 10/10/2011 16:53, Nicolas a écrit :
Le 10/10/2011 15:10, Alain Ketterlin a écrit :
Nicolas
Soit, le code suivant :
self.records = [r for r in self.records if r[self.key]<other]

Avec Python2.x, si self.key et other sont de type différents, la
comparaison retourne True ou False en fonction des types.
Avec Python3.x, ce n'est pas permis. Une exception est retournée.

Mon code modifié pour Python 3.x est :
rec = []
for r in self.records :
try :
if r[self.key]<other :
rec.append(r)
except TypeError :
pass
self.records = rec

Y a t-il une écriture plus concise possible ?



En utilisant type() ?

-- Alain.


Je n'avais pas pensé à valider les arguments avant le test.
Merci Pierre et Alain.

Nicolas


Après quelques essais, je vais garder la forme développée avec un
try/except. La validation des arguments est trop restrictive.
Par exemple, la comparaison d'un entier et d'un flottant est autorisée.
Alors que type(int) et type(float) sont différents.



Tu peux aussi utiliser un test isinstance()
http://docs.python.org/release/3.1.3/library/functions.html#isinstance
En spécifiant un tuple de plusieurs classes comme classinfo.
Nicolas
Le #23865951
Le 13/10/2011 18:24, Laurent Pointal a écrit :
Nicolas wrote:

Le 10/10/2011 16:53, Nicolas a écrit :
Le 10/10/2011 15:10, Alain Ketterlin a écrit :
Nicolas
Soit, le code suivant :
self.records = [r for r in self.records if r[self.key]<other]

Avec Python2.x, si self.key et other sont de type différents, la
comparaison retourne True ou False en fonction des types.
Avec Python3.x, ce n'est pas permis. Une exception est retournée.

Mon code modifié pour Python 3.x est :
rec = []
for r in self.records :
try :
if r[self.key]<other :
rec.append(r)
except TypeError :
pass
self.records = rec

Y a t-il une écriture plus concise possible ?



En utilisant type() ?

-- Alain.


Je n'avais pas pensé à valider les arguments avant le test.
Merci Pierre et Alain.

Nicolas


Après quelques essais, je vais garder la forme développée avec un
try/except. La validation des arguments est trop restrictive.
Par exemple, la comparaison d'un entier et d'un flottant est autorisée.
Alors que type(int) et type(float) sont différents.



Tu peux aussi utiliser un test isinstance()
http://docs.python.org/release/3.1.3/library/functions.html#isinstance
En spécifiant un tuple de plusieurs classes comme classinfo.



L'exemple avec "int" et "None" est un cas particulier qui permet de
comprendre le problème facilement.

Dans le cas qui m'intéresse, "r[self.key]" est un champ d'une base de
données et "other" est une valeur passée par l'utilisateur. Le code est
générique pour tous les champs de la base de données qui ont des types
différents et qui peuvent ne pas être renseignés (None).

L'utilisation de "isinstance()" est possible mais rendrait le code
inutilement compliqué.

Nicolas
Alain Ketterlin
Le #23866101
Nicolas
self.records = [r for r in self.records if r[self.key]<other]



En utilisant type() ?







Tu peux aussi utiliser un test isinstance()



Dans le cas qui m'intéresse, "r[self.key]" est un champ d'une base de
données



Donc il a un type, et ce type est connu.

et "other" est une valeur passée par l'utilisateur.



Donc c'est une chaîne de caractères.

Le code est générique pour tous les champs de la base de donn ées qui
ont des types différents et qui peuvent ne pas être renseignà ©s (None).



Générique ne veut pas dire que le type du champ est inconnu. A ta place
ce que je ferais est d'associer à chaque (type de) champ un comparateu r,
qui s'occupe de comparer à la valeur en provenance de l'utilisateur.

comp = comparateurs[self.key]
self.records = [r for r in self.records if comp(r[self.key],other)]

Ou, pour être un peu plus efficace, d'associer à chaque champ une
fonction qui transforme l'entrée de l'utilisateur en quelque chose de
comparable avec une valeur du champ en question. Ton code deviendrait :

ou encore

conv = convertisseurs[self.key](other)
self.records = [r for r in self.records if r[self.key] < conv]
if conv is not None else []

ou une combinaison des deux.

-- Alain.
jmfauth
Le #23866361
On 14 oct, 09:00, Nicolas

L'utilisation de "isinstance()" est possible mais rendrait le code
inutilement compliqué.





Pourquoi? C'est fait pour cela. Il me semble que la première
chose à faire avant de comparer est de trier ce qui est comparable.
Peu importe le type de donnée.

z = ['a', 1.0, 3, {}, set(), 99, None]
a = [e for e in z if isinstance(e, (int, float))]
a






[1.0, 3, 99]
other = 5
[e for e in a if e < other]






[1.0, 3]

jmf
Nicolas
Le #23875151
Le 14/10/2011 09:33, Alain Ketterlin a écrit :
Nicolas
self.records = [r for r in self.records if r[self.key]<other]













En utilisant type() ?











Tu peux aussi utiliser un test isinstance()





Dans le cas qui m'intéresse, "r[self.key]" est un champ d'une base de
données



Donc il a un type, et ce type est connu.

et "other" est une valeur passée par l'utilisateur.



Donc c'est une chaîne de caractères.


Non.
Ici, utilisateur = programmeur (utilisateur de la base de données).

Le code est générique pour tous les champs de la base de données qui
ont des types différents et qui peuvent ne pas être renseignés (None).



Générique ne veut pas dire que le type du champ est inconnu. A ta place
ce que je ferais est d'associer à chaque (type de) champ un comparateur,
qui s'occupe de comparer à la valeur en provenance de l'utilisateur.

comp = comparateurs[self.key]
self.records = [r for r in self.records if comp(r[self.key],other)]

Ou, pour être un peu plus efficace, d'associer à chaque champ une
fonction qui transforme l'entrée de l'utilisateur en quelque chose de
comparable avec une valeur du champ en question. Ton code deviendrait :

ou encore

conv = convertisseurs[self.key](other)
self.records = [r for r in self.records if r[self.key]< conv]
if conv is not None else []

ou une combinaison des deux.




Ce que je veux, c'est que le code traduit en Python3 fonctionne
exactement comme le code d'origine écrit en Python2. Pour question de
compatibilité.

Nicolas

-- Alain.
Nicolas
Le #23875141
Le 14/10/2011 11:29, jmfauth a écrit :
On 14 oct, 09:00, Nicolas

L'utilisation de "isinstance()" est possible mais rendrait le code
inutilement compliqué.





Pourquoi? C'est fait pour cela. Il me semble que la première
chose à faire avant de comparer est de trier ce qui est comparable.
Peu importe le type de donnée.

z = ['a', 1.0, 3, {}, set(), 99, None]
a = [e for e in z if isinstance(e, (int, float))]
a






[1.0, 3, 99]
other = 5
[e for e in a if e< other]






[1.0, 3]

jmf


Comme je l'ai dit à Alain :
Ce que je veux, c'est que le code traduit en Python3 fonctionne
exactement comme le code d'origine écrit en Python2. Pour question de
compatibilité.

Nicolas
Publicité
Poster une réponse
Anonyme