• 6 heures
  • Facile

Ce cours est visible gratuitement en ligne.

Ce cours est en vidéo.

Vous pouvez obtenir un certificat de réussite à l'issue de ce cours.

J'ai tout compris !

Mis à jour le 04/02/2019

Ajoutez des attributs à partir d'un dictionnaire

Connectez-vous ou inscrivez-vous gratuitement pour bénéficier de toutes les fonctionnalités de ce cours !

 

Nous avons fait une grande partie. Bravo ! Maintenant, comment "transformer" dynamiquement un élément JSON en instance de notre classeAgent ?

Si nous ouvrons notre JSON, nous voyons que chaque élément est structuré comme un dictionnaire, c'est-à-dire qu'il a des valeurs associées à chaque clé :

{"neuroticism": -0.0739192627121713, "language": "Shona", "latitude": -19.922097800281783, "country_tld": "zw", "age": 12, "income": 333, "longitude": 29.798455535838603, "sex": "Male", "religion": "syncretic", "extraversion": 1.051833688742943, "date_of_birth": "2005-01-10", "agreeableness": 0.1441229877537559, "id_str": "LB3-3Cl", "conscientiousness": 0.2419104411765549, "internet": false, "country_name": "Zimbabwe", "openness": -0.024607605122172617, "id": 6636726630}

Ce serait bien de donner ce dictionnaire en paramètre lors de l'initialisation d'une instance pour que chaque clé se transforme automatiquement en nouvel attribut. Nous pourrions le faire manuellement, autrement dit indiquer un à un le nom des attributs, mais cela va être fastidieux. Je vais vous montrer comment le faire automatiquement.

Passer un dictionnaire en paramètre

Pour l'instant, créons un nouveau dictionnaire et passons-le en paramètre. Nous verrons plus tard comment utiliser les données de notre fichier JSON.

class Agent:
    
    def __init__(self, agent_attributes):
        self.agreeableness = agent_attributes['agreeableness']

agent_attributes = {"neuroticism": -0.0739192627121713, "language": "Shona", "latitude": -19.922097800281783, "country_tld": "zw", "age": 12, "income": 333, "longitude": 29.798455535838603, "sex": "Male", "religion": "syncretic", "extraversion": 1.051833688742943, "date_of_birth": "2005-01-10", "agreeableness": 0.1441229877537559, "id_str": "LB3-3Cl", "conscientiousness": 0.2419104411765549, "internet": "false", "country_name": "Zimbabwe", "openness": -0.024607605122172617, "id": 6636726630}

first_agent = Agent(agent_attributes)
print(first_agent.agreeableness)

 

Ça fonctionne ! \o/

Afin de connaître tous les éléments d'un dictionnaire, utilisons la méthode items() :

def __init__(self, agent_attributes):
    print(agent_attributes.items())

Puis utilisons cette même méthode à l'intérieur d'une boucle afin de récupérer le nom et la valeur de chaque clé : 

def __init__(self, agent_attributes):
    for attr_name, attr_value in agent_attributes.items():
    #    set attribute

Enfin, utilisons une méthode qui s'appelle  setattr()  et qui prend en paramètre l'instance, donc self, le nom de l'attribut et la valeur de l'attribut. Comme ceci :

def __init__(self, agent_attributes):
    for attr_name, attr_value in agent_attributes.items():
        setattr(self, attr_name, attr_value)

Varier de nombre d'arguments

Python vous donne la possibilité d'avoir un nombre variable d'arguments dans une fonction. C'est très pratique lorsque vous passez à cette dernière une suite d'éléments (liste, dictionnaire, ...). 

Passer une suite d'éléments sans clé

Imaginons que vous souhaitez passer en paramètre un nombre variable d'éléments (une suite de villes, de températures, ...). Vous ne savez pas à l'avance combien de paramètres il y aura mais vous voulez tout de même les utiliser dans une fonction. Vous ajoutez dans ce cas une étoile avant la définition du paramètre.

Les éléments que vous passerez en paramètre seront transformés en tuples

Par exemple : 

def cities(country, *cities):
    print(country, cities)
    print("Type is ", type(cities))

cities("France")
# France ()
# Type is  <class 'tuple'>

cities("France", "Paris", "Mollégès", "Bourg la Reine")
# France ('Paris', 'Mollégès', 'Bourg la Reine')
# Type is  <class 'tuple'>

 

Et si nous souhaitons passer en paramètre des éléments qui ont une clé afin de les utiliser en tant que dictionnaire dans une fonction ? Nous allons dans ce cas ajouter deux étoiles. Par exemple :

def list_songs(**songs):
    print(songs)
    print("Type is ", type(songs))

list_songs()
# {}
# Type is  <class 'dict'>

list_songs(adele_songs = ["Hello", "Someone like you"], backstreet_boys_songs = ["Larger than life", "I want it that way"])
# {'adele_songs': ['Hello', 'Someone like you'], 'backstreet_boys_songs': ['Larger than life', 'I want it that way']}
# Type is  <class 'dict'>

 

Comment allons-nous utiliser ce nouveau concept dans notre code ? De la manière suivante :

class Agent:
    
    def __init__(self, **agent_attributes):
        for attr_name, attr_value in agent_attributes.items():
            setattr(self, attr_name, attr_value)

...

first_agent = Agent(**agent_attributes)
print(first_agent.agreeableness)

 

Module json

À présent, voyons comment récupérer les agents JSON et les transformer en agents Python. Nous allons utiliser le module JSON que vous connaissez déjà puisque nous l'avons utilisé dans le cours Démarrez votre projet avec Python !

Dézippons le fichier agents-100k.zip en tapant dans la console la commande suivante :

unzip agents-100k.zip

Importons le module :

import json

Puis chargeons les agents et transformons-les :

import json

class Agent:
    
    def __init__(self, **agent_attributes):
        for attr_name, attr_value in agent_attributes.items():
            setattr(self, attr_name, attr_value)

for agent_attributes in json.load(open("agents-100k.json")):
    agent = Agent(**agent_attributes)
    print(agent.agreeableness)

Nous y sommes presque !

Je commence à avoir beaucoup de commandes différentes qui s'exécutent quand je lance mon script. Vous aussi ? C'est bien ce que je me disais… Une bonne pratique est de les regrouper en une grande fonction, main(), qui sera lancée par le script. Ainsi nous savons exactement ce qui sera lancé !

Créons donc une nouvelle fonction et exécutons-la à la toute fin de notre programme :

import json

class Agent:
    
    def __init__(self, **agent_attributes):
        for attr_name, attr_value in agent_attributes.items():
            setattr(self, attr_name, attr_value)

def main():
    for agent_attributes in json.load(open("agents-100k.json")):
        agent = Agent(**agent_attributes)
        print(agent.agreeableness)
        
main()

Challenge

 Validez le challenge de ce chapitre en cliquant sur ce lien. 

 

Code du chapitre

Retrouvez le code ici : https://github.com/OpenClassrooms-Student-Center/la_poo_avec_python/tree/02_class_attributes 

Exemple de certificat de réussite
Exemple de certificat de réussite