Comment importer un module lorsque le nom du module contient un tiret «-» ou un trait d'union?


195

Je veux importer foo-bar.py. Cela marche:

foobar = __import__("foo-bar")

Cela ne:

from "foo-bar" import *

Ma question: est-il possible que je puisse utiliser le format ci-dessus, c'est- from "foo-bar" import *à- dire importer un module qui contient un module -?


10
Pourquoi avez-vous un module avec un tiret dans son nom?
Matti Virkkunen

23
Je suppose qu'il a été écrit à l'origine comme un script plutôt que comme un module.
Michael Hoffman


@MattiVirkkunen makepy.py de win32com générera un module avec un tiret dedans. dommage. comtypes a résolu ce problème en le convertissant en soulignement
swdev

2
@MattiVirkkunen Je pense que Python ne devrait pas limiter les noms que je peux donner à mes répertoires. Ce n'est pas sa responsabilité de le faire.
Zelphir Kaltstahl

Réponses:


117

tu ne peux pas. foo-barn'est pas un identifiant. renommer le fichier enfoo_bar.py

Edit: Si ce importn'est pas votre objectif (comme dans: vous ne vous souciez pas de ce qui se passe avec sys.modules, vous n'en avez pas besoin pour importer lui-même), il suffit d'obtenir tous les globaux du fichier dans votre propre portée, vous pouvez utiliserexecfile

# contents of foo-bar.py
baz = 'quux'
>>> execfile('foo-bar.py')
>>> baz
'quux'
>>> 

24
Python 3.x Nouveautés de Python 3.0 Suppression de execfile (). Au lieu d' execfile(fn)utilisation exec(open(fn).read())Il existe également le package importlib.
DevPlayer

107

Si vous ne pouvez pas renommer le module pour qu'il corresponde aux conventions de dénomination Python, créez un nouveau module qui servira d'intermédiaire:

 ---- foo_proxy.py ----
 tmp = __import__('foo-bar')
 globals().update(vars(tmp))

 ---- main.py ----
 from foo_proxy import * 

30
Je ne mettrais jamais en œuvre cela. Mais je ne peux pas ne pas donner +1 pour la brillance de ce hack
inspectorG4dget

11
vous pouvez en fait faire cela sans le foo_proxy.pyfichier, affecter la sortie de __import__(...)à sys.modules['foo_proxy']. En fait, ne faites pas ça, c'est une idée terrible.
SingleNegationElimination

3
Cool juste ce que je cherchais. Il y a un cas d'utilisation, si l'on utilise des bibliothèques natives qui sont livrées avec une distribution.
Sven


46

Si vous ne pouvez pas renommer le fichier d'origine, vous pouvez également utiliser un lien symbolique:

ln -s foo-bar.py foo_bar.py

Ensuite, vous pouvez simplement:

from foo_bar import *

2

Comme d'autres l'ont dit, vous ne pouvez pas utiliser le "-" dans la dénomination python, il existe de nombreuses solutions de contournement, une telle solution de contournement qui serait utile si vous deviez ajouter plusieurs modules à partir d'un chemin utilise sys.path

Par exemple, si votre structure est comme ceci:

foo-bar
├── barfoo.py
└── __init__.py
import sys
sys.path.append('foo-bar')

import barfoo
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.