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 :

faciliter les imports - danger(s) de cette méthode


Sujet :

Python

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre Expert Avatar de plxpy
    Homme Profil pro
    Ingénieur géographe
    Inscrit en
    Janvier 2009
    Messages
    792
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 60
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Ingénieur géographe
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Janvier 2009
    Messages : 792
    Par défaut faciliter les imports - danger(s) de cette méthode
    Bonjour

    J'écris régulièrement des packages qui sont utilisés par d'autres personnes, avec plusieurs modules et, parfois, une (petite) arborescence.

    Pour éviter que les utilisateurs aient à connaître très précisément où les classes et les fonctions sont définies et à faire des imports "compliqués", j'ai pris l'habitude d'importer, dans le fichier __init__.py du package ces classes et fonctions qu'ils auront à utiliser.

    Par exemple :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
     + package
        |__  __init__.py
        |__  module_1.py
        |__  module_2.py
    avec module_1.py :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    class Classe_1(object):
        pass
    module_2.py :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    class Classe_2(object):
        pass
    __init__.py :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    from module_1 import Classe_1
    from module_2 import Classe_2
    __all__ = ['module_1','module_2']
    Cela permet alors d'écrire dans les scripts utilisant le package :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    from package import Classe_1, Classe_2
    # plutot que
    # from package.module_1 import Classe_1
    # from package.module_2 import Classe_2
    Ca fonctionne mais je ne suis pas sur de bien mesurer les effets de bord possibles ou les inconvénients de cette méthode.
    Avez-vous un avis là dessus ?

  2. #2
    Expert éminent
    Homme Profil pro
    Architecte technique retraité
    Inscrit en
    Juin 2008
    Messages
    21 762
    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 762
    Par défaut
    Citation Envoyé par plxpy Voir le message
    Ca fonctionne mais je ne suis pas sur de bien mesurer les effets de bord possibles ou les inconvénients de cette méthode.
    Avez-vous un avis là dessus ?
    C'est une convention que j'utilise aussi.
    Vous définissez des sortes d'"alias" qui masquent l'implémentation physique. C'est une bonne chose.
    Tant que vos noms sont associés à des boîtes (classes), les "utilisateurs" pourront passer par le chemin physique ou par l'alias, sans soucis.
    Si vous avez besoin d'avoir des variables globales... danger.

    - W
    PS:
    from module_1 import Classe_1
    from module_2 import Classe_2
    __all__ = ['module_1','module_2']
    Je n'ai pas testé votre construction.
    __all__ limitant les entrées du dictionnaire importé via "from XXX import *", si __init__.py ne sert qu'à déclarer ce que vous voulez montrer, je n'en vois pas trop l'utilité.
    Ceci dit les noms que vous voulez rendre accessible sont Classe_1 et _2 et non les module_X
    Architectures post-modernes.
    Python sur DVP c'est aussi des FAQs, des cours et tutoriels

  3. #3
    Membre Expert Avatar de plxpy
    Homme Profil pro
    Ingénieur géographe
    Inscrit en
    Janvier 2009
    Messages
    792
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 60
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Ingénieur géographe
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Janvier 2009
    Messages : 792
    Par défaut
    Merci pour cette réponse wiztricks.

    C'est vrai que, si le seul but est uniquement d' "exporter" les classes Classe_1 et Classe_2, aller initialiser __all__ comme je l'ai fait n'est pas nécessaire.

    Disons que je le fais pour "ne pas fermer la porte" et rendre possible des imports plus classiques (là, pour le coup, il faut connaître finement où sont définies les classes et les fonctions - surtout si ça bouge ...).

    Ca me permet notamment, en phase de développement, d'importer des choses que je veux tester et qui, au final, sont inutiles pour les utilisateurs et qu'ils n'ont pas à importer. La documentation que j'écris indique bien de faire les imports sous la forme "from package import Classe_1" et si les utilisateurs importent autre chose, autrement, je ne réponds plus de rien !

  4. #4
    Membre Expert Avatar de plxpy
    Homme Profil pro
    Ingénieur géographe
    Inscrit en
    Janvier 2009
    Messages
    792
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 60
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Ingénieur géographe
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Janvier 2009
    Messages : 792
    Par défaut
    ... Disons que je le fais pour "ne pas fermer la porte" et rendre possible des imports plus classiques ...
    Initialiser __all__ comme je le fais(ais) n'apporte rien si ce n'est du bruit. On peut tout à fait faire des imports "complets" (explicites) sans cela. Donc c'est une habitude que je vais essayer de perdre, ça rendra __init__.py plus lisible.

  5. #5
    Membre Expert Avatar de PauseKawa
    Homme Profil pro
    Technicien Help Desk, maintenance, réseau, système et +
    Inscrit en
    Juin 2006
    Messages
    2 725
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations professionnelles :
    Activité : Technicien Help Desk, maintenance, réseau, système et +
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juin 2006
    Messages : 2 725
    Par défaut
    Bonjour,

    Citation Envoyé par plxpy Voir le message
    Initialiser __all__ comme je le fais(ais) n'apporte rien si ce n'est du bruit. On peut tout à fait faire des imports "complets" (explicites) sans cela. Donc c'est une habitude que je vais essayer de perdre, ça rendra __init__.py plus lisible.
    Et la pollution du Namespace ?
    Sans __all__
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    >>> from Foo import *
    >>> print locals()
    {'__builtins__': <module '__builtin__' (built-in)>, 'module_1': <module 'Foo.module_1' from 'Foo/module_1.pyc'>, '__package__': None, 'Classe_1': <class 'Foo.module_1.Classe_1'>, 'Classe_2': <class 'Foo.module_2.Classe_2'>, '__name__': '__main__', 'module_2': <module 'Foo.module_2' from 'Foo/module_2.pyc'>, '__doc__': None}
    Avec
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    >>> from Foo import *
    >>> print locals()
    {'__builtins__': <module '__builtin__' (built-in)>, '__package__': None, 'Classe_1': <class 'Foo.module_1.Classe_1'>, 'Classe_2': <class 'Foo.module_2.Classe_2'>, '__name__': '__main__', '__doc__': None}
    La construction de votre __init__.py ayant pour but, comme le dit wiztricks, de masquent l'implémentation physique (comprendre Pour éviter que les utilisateurs aient à connaître très précisément...) une ligne supplémentaire pour palier au non suivit de votre doc n'est pas si inutile que cela non ?
    Je ne vois pas en quoi cette construction pourrait s'avérer dangereuse dans le cadre de variables globales.

    @+

  6. #6
    Membre Expert Avatar de plxpy
    Homme Profil pro
    Ingénieur géographe
    Inscrit en
    Janvier 2009
    Messages
    792
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 60
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Ingénieur géographe
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Janvier 2009
    Messages : 792
    Par défaut
    @PauseKawa

    Concernant le Namespace, quand j'importe tout du package, je n'ai pas la même chose que toi (du coup j'ai essayé en 2.6 et en 2.7 mais ça ne change rien).

    Sans initialisation de __all__

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    plx@sony:~/Bureau$ python2.6
    Python 2.6.5 (r265:79063, Apr 16 2010, 13:09:56) 
    [GCC 4.4.3] on linux2
    Type "help", "copyright", "credits" or "license" for more information.
    >>> from pprint import pprint
    >>> from package import *
    >>> pprint(locals())
    {'Classe_1': <class 'package.module_1.Classe_1'>,
     'Classe_2': <class 'package.module_2.Classe_2'>,
     '__builtins__': <module '__builtin__' (built-in)>,
     '__doc__': None,
     '__name__': '__main__',
     '__package__': None,
     'module_1': <module 'package.module_1' from 'package/module_1.py'>,
     'module_2': <module 'package.module_2' from 'package/module_2.py'>,
     'pprint': <function pprint at 0xb777c56c>}
    >>>
    avec initialisation __all__ = ['module_1','module_2']

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    plx@sony:~/Bureau$ python2.6
    Python 2.6.5 (r265:79063, Apr 16 2010, 13:09:56) 
    [GCC 4.4.3] on linux2
    Type "help", "copyright", "credits" or "license" for more information.
    >>> from pprint import pprint
    >>> from package import *
    >>> pprint(locals())
    {'__builtins__': <module '__builtin__' (built-in)>,
     '__doc__': None,
     '__name__': '__main__',
     '__package__': None,
     'module_1': <module 'package.module_1' from 'package/module_1.pyc'>,
     'module_2': <module 'package.module_2' from 'package/module_2.pyc'>,
     'pprint': <function pprint at 0xb76ea56c>}
    >>>
    c'est-à-dire que sans initialisation de __all__, on a 2 noms visibles supplémentaires, Classe_1 et Classe_2.

    Du coup, j'ai l'impression qu'on n'est pas phasé pour discuter des avantages/inconvénients de la chose.
    Travaillerais-tu en version 3 ? Est-ce que cela pourrait expliquer les différences dans locals() ?

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

Discussions similaires

  1. [Débutant] Pouvez-vous m'expliquer cette méthode sur les expressions
    Par jacko842 dans le forum C#
    Réponses: 4
    Dernier message: 27/05/2015, 11h44
  2. [PHP 5.3] Améliorer cette méthode pour utiliser les marqueurs PDO
    Par beegees dans le forum Langage
    Réponses: 1
    Dernier message: 18/08/2012, 19h45
  3. Prendre que les 5 premiers enregistrements (les + important)
    Par __fabrice dans le forum MS SQL Server
    Réponses: 3
    Dernier message: 02/11/2005, 09h24
  4. [Plugin] Factoriser les import (gestion des import)
    Par Oliveuh dans le forum Eclipse Java
    Réponses: 1
    Dernier message: 08/07/2004, 12h21

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