J'aimerais proposer ma version, qui est une combinaison de la solution de Boaz Yaniv et de celle d'Omnifarious. Elle permet d'importer la version système d'un module, avec deux différences principales par rapport aux réponses précédentes :
- Supporte la notation "point", par exemple package.module
- Il s'agit d'un remplacement immédiat de l'instruction d'importation des modules du système, ce qui signifie qu'il suffit de remplacer cette ligne et que si des appels sont déjà faits au module, ils fonctionneront tels quels.
Mettez-le dans un endroit accessible pour que vous puissiez l'appeler (j'ai le mien dans mon fichier __init__.py) :
class SysModule(object):
pass
def import_non_local(name, local_module=None, path=None, full_name=None, accessor=SysModule()):
import imp, sys, os
path = path or sys.path[1:]
if isinstance(path, basestring):
path = [path]
if '.' in name:
package_name = name.split('.')[0]
f, pathname, desc = imp.find_module(package_name, path)
if pathname not in __path__:
__path__.insert(0, pathname)
imp.load_module(package_name, f, pathname, desc)
v = import_non_local('.'.join(name.split('.')[1:]), None, pathname, name, SysModule())
setattr(accessor, package_name, v)
if local_module:
for key in accessor.__dict__.keys():
setattr(local_module, key, getattr(accessor, key))
return accessor
try:
f, pathname, desc = imp.find_module(name, path)
if pathname not in __path__:
__path__.insert(0, pathname)
module = imp.load_module(name, f, pathname, desc)
setattr(accessor, name, module)
if local_module:
for key in accessor.__dict__.keys():
setattr(local_module, key, getattr(accessor, key))
return module
return accessor
finally:
try:
if f:
f.close()
except:
pass
Exemple
Je voulais importer mysql.connection, mais j'avais déjà un paquet local appelé mysql (les utilitaires officiels de mysql). Donc pour obtenir le connecteur à partir du paquet mysql du système, j'ai remplacé ceci :
import mysql.connector
Avec ça :
import sys
from mysql.utilities import import_non_local # where I put the above function (mysql/utilities/__init__.py)
import_non_local('mysql.connector', sys.modules[__name__])
Résultat
# This unmodified line further down in the file now works just fine because mysql.connector has actually become part of the namespace
self.db_conn = mysql.connector.connect(**parameters)
25 votes
C'est une bonne pratique de ne pas nommer les modules pour cacher les modules intégrés.
3 votes
La solution est de "choisir un autre nom". Votre approche consistant à ne pas changer de nom est une mauvaise idée. Pourquoi ne pouvez-vous pas renommer votre module ? Quel est le problème avec le renommage ?
0 votes
En effet. C'est parce qu'il y a pas de bonne réponse à cette question que l'observation des modules stdlib est si fortement déconseillée.
0 votes
J'ai évité d'utiliser le même nom de module, car les solutions me semblaient plus compliquées qu'elles ne le sont. Merci !
13 votes
Ce conseil n'est pas valable, purement et simplement. PEP328 le reconnaît volontiers.
0 votes
Voir ma réponse ici : stackoverflow.com/questions/12011327/
0 votes
J'ai eu un problème similaire et je suis tombé sur cette question. Je l'ai résolu avec
from __future__ import absolute_import
Comme ça, quand jeimport module_name
J'ai eu la bibliothèque mais quand j'ai faitimport mypackage.module_name
J'ai le module local.