IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Python Discussion :

Bonnes pratiques lors de l'import d'un module [Python 3.X]


Sujet :

Python

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre expérimenté

    Profil pro
    En reconversion
    Inscrit en
    Novembre 2007
    Messages
    180
    Détails du profil
    Informations personnelles :
    Localisation : France, Morbihan (Bretagne)

    Informations professionnelles :
    Activité : En reconversion

    Informations forums :
    Inscription : Novembre 2007
    Messages : 180
    Par défaut Bonnes pratiques lors de l'import d'un module
    Bonjour,

    Je connais 3 façons d'importer un module, par exemple :
    - import os
    - from os import *
    - from os import geteuid (exemple au hasard)

    La deuxième méthode n'est à priori pas recommandé, au profit de la première.
    Avec la première méthode, il faut préciser l'espace de nom avec chaque appel d'une méthode ou autre, par exemple os.geteuid().
    Alors qu'avec la troisième méthode, on peut directement appelé geteuid() (à condition qu'il n'y ait pas de collision avec le module en cours bien sûr).

    Débutant en python, je ne connais pas tous les noms des méthodes et lorsque je lis des exemples, je suis souvent perdu, et je dois rechercher à quel espace de nom fait référence chaque méthode, car ils utilisent généralement la troisième méthode. En effet, il est courant que des exemples soient restreints et ne présentent pas l'intégralité du code. Ce qui parait limpide pour certains ne l'est pas forcément pour les autres.

    Ainsi pour me retrouver dans mon code, j'ai envie d'utiliser la première méthode et de préciser l'espace de nom à chaque fois, quitte à créer un alias plus court. J'ai pris cette habitude en écrivant du sql (cela ne peut qu'optimiser le traitement par le moteur).
    Cependant, j'ai peur qu'avec la première méthode cela oblige à charger tout le module et donc à surcharger la mémoire inutilement. Est ce que ma peur est avérée ? je ne connais pas les entrailles de python pour y répondre, mais peut être quelqu'un parmi vous ?

    Merci pour votre aide.

  2. #2
    Expert confirmé

    Homme Profil pro
    Inscrit en
    Octobre 2008
    Messages
    4 307
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations forums :
    Inscription : Octobre 2008
    Messages : 4 307
    Par défaut
    Salut,

    L'import de modules est un mécanisme assez complexe avec Python, mais on peut généralement simplifier en disant que seul ce qui est nécessaire à l'exécution du code est chargé en mémoire et seulement au moment utile.

    Je ne pense pas qu'il y ait plus intérêt à utiliser la première ou la troisième méthode, ça me semble plus une question d'habitude.

  3. #3
    Membre Expert
    Homme Profil pro
    Enseignant
    Inscrit en
    Juin 2013
    Messages
    1 617
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Enseignant
    Secteur : Enseignement

    Informations forums :
    Inscription : Juin 2013
    Messages : 1 617
    Par défaut
    Il y en a une quatrième, c'est d'utiliser un alias, par exemple :
    puis ensuite, par exemple
    Cela permet de savoir par exemple qu'on utilise la fonction sinus du module numpy et non celle du module math, dont le comportement peut être différent.

  4. #4
    Expert confirmé
    Avatar de tyrtamos
    Homme Profil pro
    Retraité
    Inscrit en
    Décembre 2007
    Messages
    4 486
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Var (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Décembre 2007
    Messages : 4 486
    Billets dans le blog
    6
    Par défaut
    Bonjour,

    Il m'est déjà arrivé d'utiliser un alias dans un cas un peu particulier. La fonction pow de base (exponentiation x**y) permet un 3ème argument pour faire une exponentiation modulaire. Mais pas la fonction pow du module math! Alors, quand on installe math avec "from math import *", le pow de math masque le pow de base, et la partie modulaire devient impossible.

    La solution: faire comme ça:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    from builtins import pow as powmod
    from math import *
     
    print(powmod(2,3,2)) # => utilisation du pow de base
    print(pow(2,3)) # => utilisation du pow de math
    Autre remarque sur le sujet: dans certains cas de programme, la 3ème solution est meilleure sur le plan sécurité parce qu'elle permet d'éviter certaines injections.

    Enfin, ne pas oublier des outils comme pylint pendant le développement: cet outil permet de détecter les importations inutiles ou manquantes. On peut donc commencer par une importation "attrappe tout" (from xxx import *) pendant le développement, et préciser à la fin la liste des objets à importer en utilisant pylint.

  5. #5
    Membre expérimenté

    Profil pro
    En reconversion
    Inscrit en
    Novembre 2007
    Messages
    180
    Détails du profil
    Informations personnelles :
    Localisation : France, Morbihan (Bretagne)

    Informations professionnelles :
    Activité : En reconversion

    Informations forums :
    Inscription : Novembre 2007
    Messages : 180
    Par défaut
    Merci pour vos réponses.

    Donc l'utilisation de la première méthode n'impacterait pas la mémoire plus que nécessaire ?

    Effectivement, je connais la notation avec un alias, et c'est d'ailleurs la pratique que je préfère, car comme vous l'avez dit, cela permet plus facilement d’identifier l'espace de nom utilisé.

    D'autres avis peut être ?

  6. #6
    Membre expérimenté

    Profil pro
    En reconversion
    Inscrit en
    Novembre 2007
    Messages
    180
    Détails du profil
    Informations personnelles :
    Localisation : France, Morbihan (Bretagne)

    Informations professionnelles :
    Activité : En reconversion

    Informations forums :
    Inscription : Novembre 2007
    Messages : 180
    Par défaut
    Je viens seulement de lire la dernière réponse.

    Je ne connaissais pas la notation avec un alias sur la forme "from x import y as z". Cela pourrait être une solution à mon problème.

    Je pensais que dans le cas d'une collision entre deux fonctions de même nom, cela levait une exception. C'est d'autant plus dangereux, car on ne sait pas quelle fonction est réellement appelée. Je viens d'essayer en créant la fonction pi() dans mon code et en important pi du module math en entête, et c'est ma fonction qui a été retenue (à cause de l'ordre dans le code apparemment). Je n'aime pas ce genre de comportement ambigu.

    Je n'ai pas compris le problème de sécurité (injection).

    Sinon, je débute et je ne connais pas encore les différentes possibilités d'amélioration du code, mais j'y travaille, donc merci pour l'astuce concernant pylint.

  7. #7
    Expert éminent
    Homme Profil pro
    Architecte technique retraité
    Inscrit en
    Juin 2008
    Messages
    21 743
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Manche (Basse Normandie)

    Informations professionnelles :
    Activité : Architecte technique retraité
    Secteur : Industrie

    Informations forums :
    Inscription : Juin 2008
    Messages : 21 743
    Par défaut
    Salut,

    Citation Envoyé par patic Voir le message
    Ainsi pour me retrouver dans mon code, j'ai envie d'utiliser la première méthode et de préciser l'espace de nom à chaque fois, quitte à créer un alias plus court. J'ai pris cette habitude en écrivant du sql (cela ne peut qu'optimiser le traitement par le moteur).
    Cependant, j'ai peur qu'avec la première méthode cela oblige à charger tout le module et donc à surcharger la mémoire inutilement. Est ce que ma peur est avérée ? je ne connais pas les entrailles de python pour y répondre, mais peut être quelqu'un parmi vous ?
    Quelque soit la méthode, le module sera chargé (si d'autres "import" ne l'ont pas déjà fait).
    Pour le reste ce qui change, c'est d'abord les variables ajoutés à l'espace globals():
    • import os: seul "os" sera ajouté,
    • from os import *: toutes les variables publiques du module sont ajoutées.
    • from os import geteuid: seul "getuid" sera ajouté...

    Au plus il y aura d'ajouts, au plus la durée de l'import sera longue. Ce qui fera préférer les formes 1 et 3 à la deuxième.... Et réserver la deuxième plutôt à des tests avec l'interpréteur interactif (ce qui évite d'avoir à tout taper).

    Donc il vous reste 1 ou 3... et c'est sur que liste "os.geteuid" sera probablement plus parlant que "geteuid" tout seul. Et côté performances, trouver à quoi est associé "os" puis récupérer l'objet associé à "geteuid", çà fait une indirection qui peut être sensible lorsqu'on fait des itérations.
    (mais rien n'interdit d'optimiser avec la création d'une variable "locale" geteuid = os.geteuid juste avant ces itérations).

    D'autre part, au plus vous allez progresser au plus vous utiliserez des objets, utiliser des variables associées à un espace de noms autre que globals(): instance.machin, module.truc,... sont des notations qui alertent sur le fait que "machin" et "truc" ne sont ni variables locales ni variables globales mais viennent d'ailleurs...

    Pour ce qui est des alias - import numpy as np -, ils permettent d'abord de vous éviter de taper trop de caractères mais dans le cas "import Tkinter as tk" de Python2 vs. "import tkinter as tk" de Python3, çà permet aussi de réduire les changements à faire dans le code lorsque le nom du module change.

    Je n'ai fait que lister quelques bonnes raisons de préférer une forme par rapport à une autre. Mais dans la vraie vie, il y a toujours des exceptions qui rendent illusoire de vouloir appliquer la même règle partout. Il faut donc s'adapter au contexte (et savoir pourquoi on fait ici et maintenant un peu différemment de ce qu'on a pu faire hier).

    En tous cas, bonne année à tous.

    - W
    Architectures post-modernes.
    Python sur DVP c'est aussi des FAQs, des cours et tutoriels

  8. #8
    Membre expérimenté

    Profil pro
    En reconversion
    Inscrit en
    Novembre 2007
    Messages
    180
    Détails du profil
    Informations personnelles :
    Localisation : France, Morbihan (Bretagne)

    Informations professionnelles :
    Activité : En reconversion

    Informations forums :
    Inscription : Novembre 2007
    Messages : 180
    Par défaut
    Merci pour ces explications fort intéressantes,

    et bonne année à vous tous également

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Bonnes pratiques de protections individuelles
    Par Community Management dans le forum Sécurité
    Réponses: 23
    Dernier message: 11/06/2024, 11h23
  2. [Python 3.X] Import dans des modules? Comment faire et quelles sont les bonnes pratiques?
    Par Davjack dans le forum Général Python
    Réponses: 2
    Dernier message: 03/07/2014, 12h13
  3. Réponses: 2
    Dernier message: 02/01/2014, 17h49
  4. Conversion de date lors d'un import
    Par bilbon.S dans le forum SQL Procédural
    Réponses: 4
    Dernier message: 26/03/2004, 14h33

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo