Como importar o módulo quando o nome do módulo possui um traço '-' ou hífen?


193

Eu quero importar foo-bar.py. Isso funciona:

foobar = __import__("foo-bar")

Isto não:

from "foo-bar" import *

Minha pergunta: Existe alguma maneira de usar o formato acima, ou seja, from "foo-bar" import *para importar um módulo que contenha um -?


10
Por que você tem um módulo com um traço no nome?
Matti Virkkunen

22
Suponho que foi originalmente escrito como um script, e não como um módulo.
Michael Hoffman


@MattiVirkkunen makepy.py do win32com irá gerar o módulo com o traço nele. que pena. comtypes resolvido este, convertendo-a sublinhado
swdev

2
@MattiVirkkunen Acho que o Python não deve limitar os nomes que posso dar aos meus diretórios. Não é sua responsabilidade fazê-lo.
Zelphir Kaltstahl

Respostas:


116

você não pode. foo-barnão é um identificador. renomeie o arquivo parafoo_bar.py

Edit: Se importnão é o seu objetivo (como em: você não se importa o que acontece com sys.modules, você não precisa dele para importar-se), apenas recebendo todos globals do arquivo em seu próprio escopo, você pode usarexecfile

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

24
Python 3.x O que há de novo no Python 3.0 Removido execfile (). Em vez de execfile(fn)usar exec(open(fn).read())Também há o pacote importlib.
DevPlayer

104

Se você não pode renomear o módulo para corresponder às convenções de nomenclatura do Python, crie um novo módulo para atuar como intermediário:

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

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

28
Eu nunca implementaria isso. Mas eu não posso deixar de dar +1 pelo puro brilho desse hack
inspectorG4dget

11
você pode realmente fazer isso sem o foo_proxy.pyarquivo, atribua a saída de __import__(...)para sys.modules['foo_proxy']. Na verdade, não faça isso, é uma péssima ideia.
SingleNegationElimination

3
Legal, exatamente o que eu estava procurando. Existe um caso de usuário, se alguém usar bibliotecas nativas enviadas com uma distribuição.
Sven


46

Se você não pode renomear o arquivo original, também pode usar um link simbólico:

ln -s foo-bar.py foo_bar.py

Então você pode apenas:

from foo_bar import *

2

Como outros disseram que você não pode usar o "-" na nomeação python, existem muitas soluções alternativas, uma solução alternativa que seria útil se você tivesse que adicionar vários módulos de um caminho usando sys.path

Por exemplo, se sua estrutura é assim:

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

import barfoo
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.