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 -?

Bala
la source
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
1
duplication possible du module Python avec un tiret, ou un tiret (-) dans son nom
Piotr Dobrogost
@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'
>>> 
SingleNegationElimination
la source
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 * 
Raymond Hettinger
la source
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 *
gitaarik
la source
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
Reda Drissi
la source