Как импортировать модуль, если в имени модуля есть тире или дефис '-'?


195

Я хочу импортировать foo-bar.py. Это работает:

foobar = __import__("foo-bar")

Это не:

from "foo-bar" import *

Мой вопрос: есть ли способ, которым я могу использовать вышеуказанный формат, т.е. from "foo-bar" import *импортировать модуль, в котором есть -?


10
Почему у вас есть модуль с тире в его названии?
Матти Вирккунен

23
Я предполагаю, что изначально он был написан как скрипт, а не как модуль.
Майкл Хоффман


@MattiVirkkunen makepy.py из win32com создаст модуль с чертой в нем. жаль. comtypes решили эту проблему, преобразовав ее в подчеркивание
swdev

2
@ MattiVirkkunen Я думаю, что Python не должен ограничивать имена, которые я могу дать своим каталогам. Это не является его обязанностью сделать это.
Зельфир Кальцталь

Ответы:


117

ты не можешь foo-barне является идентификатором. переименовать файл вfoo_bar.py

Изменить: Если importне ваша цель (как в: вам все равно, что происходит sys.modules, вам не нужно импортировать саму себя), просто перенесите все глобальные переменные файла в свою область видимости, вы можете использоватьexecfile

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

24
Python 3.x Что нового в Python 3.0 Удалено execfile (). Вместо execfile(fn)использования exec(open(fn).read())также есть пакет importlib.
DevPlayer

107

Если вы не можете переименовать модуль в соответствии с соглашениями об именах Python, создайте новый модуль, который будет выступать в качестве посредника:

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

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

30
Я бы никогда этого не реализовал. Но я не могу не дать +1 для явного блеска этого хака
inspectorG4dget

11
Вы могли бы сделать это без foo_proxy.pyфайла, назначив вывод __import__(...)для sys.modules['foo_proxy']. На самом деле, не делай этого, это ужасная идея.
SingleNegationElimination

3
Круто только то, что я искал. Существует вариант использования, если вы используете нативные библиотеки, которые поставляются с дистрибутивом.
Свен


46

Если вы не можете переименовать исходный файл, вы также можете использовать символическую ссылку:

ln -s foo-bar.py foo_bar.py

Тогда вы можете просто:

from foo_bar import *

2

Как и другие говорили, что вы не можете использовать «-» в именовании Python, есть много обходных путей, один из таких обходных путей, который будет полезен, если вам нужно добавить несколько модулей из пути, использует sys.path

Например, если ваша структура такая:

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

import barfoo
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.