Jak zaimportować moduł, gdy nazwa modułu zawiera myślnik lub myślnik?

195

Chcę zaimportować plik foo-bar.py. To działa:

foobar = __import__("foo-bar")

To nie:

from "foo-bar" import *

Moje pytanie: Czy jest jakiś sposób, aby użyć powyższego formatu, tj. from "foo-bar" import *Zaimportować moduł, który ma -w nim format ?

Bala
źródło
10
Dlaczego masz moduł z myślnikiem w nazwie?
Matti Virkkunen,
23
Domyślam się, że pierwotnie został napisany jako skrypt, a nie jako moduł.
Michael Hoffman,
1
możliwy duplikat Pythona z myślnikiem lub myślnikiem (-) w jego nazwie
Piotr Dobrogost
@MattiVirkkunen makepy.py z win32com wygeneruje moduł z kreską w nim. szkoda. comtypes rozwiązał ten problem, przekształcając go w podkreślenie
swdev
2
@MattiVirkkunen Myślę, że Python nie powinien ograniczać nazwisk, które mogę podać swoim katalogom. Nie jest to odpowiedzialny za to.
Zelphir Kaltstahl

Odpowiedzi:

117

nie możesz. foo-barnie jest identyfikatorem. zmień nazwę pliku nafoo_bar.py

Edycja: Jeśli importnie jest to Twoim celem (jak w: nie obchodzi Cię, co się stanie sys.modules, nie musisz go importować), po prostu umieszczając wszystkie globale pliku we własnym zakresie, możesz użyćexecfile

# contents of foo-bar.py
baz = 'quux'
>>> execfile('foo-bar.py')
>>> baz
'quux'
>>> 
SingleNegationElimination
źródło
24
Python 3.x Co nowego w Python 3.0 Usunięto plik wykonywalny (). Zamiast execfile(fn)używać exec(open(fn).read())Istnieje również pakiet importlib.
DevPlayer
106

Jeśli nie możesz zmienić nazwy modułu, aby pasował do konwencji nazewnictwa Python, utwórz nowy moduł, który będzie działał jako pośrednik:

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

 ---- main.py ----
 from foo_proxy import * 
Raymond Hettinger
źródło
30
Nigdy bym tego nie wdrożył. Ale nie mogę nie dać +1 za czysty blask tego hacka
inspectorG4dget
11
możesz to zrobić bez foo_proxy.pypliku, przypisz wynik __import__(...)do sys.modules['foo_proxy']. Właściwie nie rób tego, to okropny pomysł.
SingleNegationElimination,
3
Fajnie tylko to, czego szukałem. Istnieje przypadek użycia, jeśli używa się bibliotek rodzimych dostarczanych z dystrybucją.
Sven
46

Jeśli nie możesz zmienić nazwy oryginalnego pliku, możesz również użyć dowiązania symbolicznego:

ln -s foo-bar.py foo_bar.py

Następnie możesz po prostu:

from foo_bar import *
gitaarik
źródło
2

Jak inni powiedzieli, że nie można używać „-” w nazewnictwie python, istnieje wiele obejść, jedno takie obejście, które byłoby przydatne, gdybyś musiał dodać wiele modułów ze ścieżki używa sys.path

Na przykład, jeśli twoja struktura jest taka:

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

import barfoo
Reda Drissi
źródło