Excellent exemple pour python2 ici . Ma traduction en python3 (illustrée ci-dessous) fonctionne dans tous mes tests.
def convert(data):
if isinstance(data, bytes):
return data.decode('ascii')
Elif isinstance(data, dict):
return dict(map(convert, data.items()))
Elif isinstance(data, Tuple):
return map(convert, data)
else:
return data
On dirait que j'utilise beaucoup cela pour des bibliothèques qui ont été portées de py2 à py3.
Quelqu'un at-il une meilleure conception pour la même tâche? Celui-ci pourrait-il être optimisé?
Je ne sais pas pour l'optimisation de la vitesse mais je suis pas un grand fan de if/return/else
paradigme car il obstrue le code avec des trucs inutiles et provoque des escaliers d'indentation pour les langues sans Elif
(ce n'est pas un problème ici).
En optimisant pour lisibilité (qui est généralement ma première préférence), je transformerais toutes ces lignes Elif
en if
et abandonnerais complètement le else
, reformatage pour le rendre plus compact:
def convert(data):
if isinstance(data, bytes): return data.decode('ascii')
if isinstance(data, dict): return dict(map(convert, data.items()))
if isinstance(data, Tuple): return map(convert, data)
return data
L'extension de la réponse de paxdiablo pour gérer plus de cas d'utilisation a donné les résultats suivants:
def convert(data):
if isinstance(data, bytes): return data.decode()
if isinstance(data, (str, int)): return str(data)
if isinstance(data, dict): return dict(map(convert, data.items()))
if isinstance(data, Tuple): return Tuple(map(convert, data))
if isinstance(data, list): return list(map(convert, data))
if isinstance(data, set): return set(map(convert, data))
Il devient clair que l'application de la fonction de carte est assez cohérente et nous pouvons la généraliser.
def convert(data):
data_type = type(data)
if data_type == bytes: return data.decode()
if data_type in (str, int): return str(data)
if data_type == dict: data = data.items()
return data_type(map(convert, data))
Le moyen le plus simple serait d'utiliser la compréhension du dictionnaire comme suit:
new_data = { key.decode(): val.decode() for key, val in data.items() }
Exemple:
>>> data = {
... b'cart1': b'apples',
... b'cart2': b'oranges',
... b'cart3': b'grapes'
... }
>>>
>>> new_data = { key.decode(): val.decode() for key, val in data.items() }
>>>
>>> new_data
{'cart1': 'apples', 'cart2': 'oranges', 'cart3': 'grapes'}
>>>
Pour convertir des paires de valeurs de clés d'octets de type dans un ordre aléatoire, utilisez:
new_data = {
key.decode() if isinstance(key, bytes) else key:
val.decode() if isinstance(val, bytes) else val
for key, val in data.items()
}
Exemple:
>>> data = {
... b'cart1': 'apples',
... 'cart2': b'oranges',
... b'cart3': b'grapes'
... }
>>>
>>> new_data = {
... key.decode() if isinstance(key, bytes) else key:
... val.decode() if isinstance(val, bytes) else val
... for key, val in data.items()
... }
>>> new_data
{'cart1': 'apples', 'cart2': 'oranges', 'cart3': 'grapes'}
>>>
Remarque: Le code ci-dessus sera meilleur pour un dictionnaire de données simple. Mais pour les dictionnaires complexes, je préférerais utiliser le code de Guy Gangemi qui est une modification de paxdiablo réponse:
def convert(data):
if isinstance(data, bytes): return data.decode()
if isinstance(data, dict): return dict(map(convert, data.items()))
if isinstance(data, Tuple): return Tuple(map(convert, data))
if isinstance(data, list): return list(map(convert, data))
return data
Exemple:
>>>
>>> def convert(data):
... if isinstance(data, bytes): return data.decode()
... if isinstance(data, dict): return dict(map(convert, data.items()))
... if isinstance(data, Tuple): return Tuple(map(convert, data))
... if isinstance(data, list): return list(map(convert, data))
... return data
...
>>>
>>> data = {
... b'fruits': {
... b'cart1': b'apples',
... b'cart2': 'oranges',
... b'cart3': b'grapes',
... b'cart4': (b'banana', 'pear'),
... b'cart5': [b'kiwi', b'papaya']
... },
... 'vegetables': {
... 'cart1': b'carrots',
... b'cart2': None,
... b'cart3': {},
... b'cart4': False
... }
... }
>>>
>>> convert(data)
{'fruits': {'cart1': 'apples', 'cart2': 'oranges', 'cart3': 'grapes', 'cart4': ('banana', 'pear'), 'cart5': ['kiwi', 'papaya']}, 'vegetables': {'cart1': 'carrots', 'cart2': None, 'cart3': {}, 'cart4': False}}
>>>