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.