W Pythonie sposób importowania nazwy pliku zaczyna się od liczby

84

Zasadniczo istnieje plik o nazwie 8puzzle.pyi chcę zaimportować plik do innego pliku (w tym samym folderze i nie mogę zmienić nazwy pliku, ponieważ plik jest dostarczony). Czy w ogóle można to zrobić w Pythonie? Próbowałem jak zwykle from 8puzzle import *, daje mi to błąd.

Błąd:

>>> import 8puzzle
  File "<input>", line 1
    import 8puzzle
           ^
SyntaxError: invalid syntax
>>> 
Simon Guo
źródło
12
Dlaczego ludzie mówią „daje mi [] błąd”, a potem nie publikują, co to za błąd?
John Zwinck,
7
@JohnZwinck To błąd składniowy. Zgaduję, ponieważ „8puzzle” nie jest prawidłowym identyfikatorem (zaczyna się od liczby), a składnia instrukcji importu wymaga tam identyfikatora Pythona. Co oznaczałoby odpowiedź „Nie, nie możesz. Zmień nazwę modułu na taką, która zaczyna się od litery lub podkreślenia”.
millimoose
John miał rację, będę o tym pamiętać. Dzięki Abhijeet dodaj mi komunikat o błędzie. Dzięki.
Simon Guo
1
Zmień nazwę 8puzzle.pyna puzzle8.pyi użyj import puzzle8.
Bakuriu,

Odpowiedzi:

96

Mógłbyś

puzzle = __import__('8puzzle')

Bardzo ciekawy problem. Będę pamiętał, żeby niczego nie nazwać numerem.

Jeśli chcesz import *- zapoznaj się z tym pytaniem i odpowiedzią .

Yuji „Tomita” Tomita
źródło
1
działa świetnie! dzięki. tak, nie nazwałbym go numerem, ale jest to plik z informacją o projekcie kursu, więc nie mogę zmienić nazwy. Ale wydaje się, że nie ma to znaczenia, ponieważ już mamy na to rozwiązanie. Dzięki jeszcze raz.
Simon Guo
4
Pomóż ocalić świat, a przynajmniej swoich kolegów z klasy. Jeśli otrzymasz niemożliwy import, zwróć na to uwagę instruktora. Tak, czasami nienawidzą się mylić, ale jeśli masz ten problem, wszyscy inni też i chociaż ta odpowiedź działa, nie jest to właściwe rozwiązanie (chyba że klasa to „Obfuscated Python 101”).
msw
1
Lepszym sposobem (przynajmniej w Pythonie 2.7) jest użycie modułu 'importlib': puzzle = importlib.import_module ('8puzzle')
Cédric
3
W rzeczywistości jest to dobry przypadek użycia - jako część procesu kompilacji / produkcji, łączenie modułów Pythona ze sobą jest najłatwiejsze, jeśli są nazwane w formie leksigraficznej (generalnie nie ma to znaczenia, ale stałe i importy na górze, jeśli nazwa 'na dole, więc kilka modułów zaczynających się od' 0 'może być użytecznych.) Przydatne również w debugowaniu tak nietypowego układu katalogów, w połączeniu z inotify lub watch, coś takiego: watch -n .1' cat * | python ', który ładowałby twoją aplikację pythona co dziesiąte sekundy (lub przynajmniej tak szybko, jak to możliwe) lub: cat $ (find. -name "* .py") | python
fatal_error
1
Spóźniony na imprezę, ale innym przypadkiem użycia jest importowanie z migracji Alembic, ponieważ wszystkie zaczynają się od losowych skrótów
kevlarr
35

Powyższe odpowiedzi są poprawne, ale na razie zalecanym sposobem jest użycie import_modulefunkcji:

importlib.import_module(name, package=None)
Zaimportuj moduł. Argument nazwa określa, który moduł importować w kategoriach bezwzględnych lub względnych (np. Albo pkg.modalbo ..mod). Jeśli nazwa jest określona w kategoriach względnych, to argument pakietu musi być ustawiony na nazwę pakietu, która ma działać jako kotwica do rozpoznawania nazwy pakietu (np. import_module('..mod', 'pkg.subpkg')Importuje pkg.mod).

Funkcja import_module () działa jak uproszczone opakowanie importlib.__import__(). Oznacza to, że cała semantyka funkcji pochodzi zimportlib.__import__() . Najważniejsza różnica między tymi dwiema funkcjami polega na tym, że import_module()zwraca określony pakiet lub moduł (np. pkg.mod), A __import__()zwraca pakiet lub moduł najwyższego poziomu (np pkg.).

Jeśli dynamicznie importujesz moduł, który został utworzony od czasu, gdy interpreter rozpoczął wykonywanie (np. Utworzył plik źródłowy w języku Python), może być konieczne wywołanie invalidate_caches() , aby nowy moduł został zauważony przez system importu.

__import__ nie jest teraz zalecane.

importlib.__import__(name, globals=None, locals=None, fromlist=(), level=0)
Implementacja funkcji wbudowanej __import__().

Uwaga Programmatic import modułów powinien używać import_module()zamiast tej funkcji.

laike9m
źródło
Działa dzięki, ale nie działa importowanie funkcji lub zmiennej w jednym z tych plików zaczynających się od liczby. Jeśli tak: an_imported_file = importlib.import_module('13_file')to nie mogę from an_imported_file import var_x. Czy jest coś, co można zrobić, aby to osiągnąć?
Martin
/usr/local/bin/python3.7 "/Users/constan/Desktop/2_COData/1_PYTHON /CODEX/13_Spacy/children.py" Traceback (most recent call last): File "/Users/constan/Desktop/2_COData/1_PYTHON /CODEX/13_Spacy/children.py", line 7, in <module> from an_imported_file import var_x ModuleNotFoundError: No module named 'an_imported_file'
Martin
Również wiersz `from an_imported_file import var_x 'w Pycharm jest podkreślony na czerwono ...
Martin
Nie wiem, przepraszam. Moja ogólna rada jest taka, aby tego unikać.
laike9m
0

Nie używaj .py rozszerzenia w imporcie.

Robi from 8puzzle import * ?

Tyle ile jest warte, from x import * nie jest preferowanym wzorcem Pythona, ponieważ upuszcza przestrzeń nazw tego modułu do bieżącego kontekstu.

Ogólnie rzecz biorąc, spróbuj zaimportować wybrane rzeczy z tego modułu. Można zaimportować dowolny globalny z innego modułu.

np. jeśli masz 8puzzle.foo możesz zrobić `from 8puzzle import

Edytować:

Podczas gdy mój .py wiadomość jest poprawna, nie wystarczy.

__import__('8puzzle')Sugestia drugiego autora jest poprawna. Jednak bardzo polecam unikanie tego schematu .

Po pierwsze, jest to zarezerwowana wewnętrzna, prywatna metoda Pythona. Zasadniczo łamiesz podstawowe założenia dotyczące możliwości zaimportowania modułu. Po prostu zmień nazwę pliku na inną, na przykładpuzzle8 , rozwiązuje ten problem.

Spowoduje to cholerną frustrację doświadczonych programistów Pythona, którzy oczekują, że będą wiedzieć, jakie importowane pliki znajdują się na szczycie i oczekują, że kod (spróbuje) być zgodny z PEP8 .

mvanveen
źródło
1
przepraszam za zamieszanie. Zrobiłem from 8puzzle import *i zredagowałem moje oryginalne pytanie. I nie działa tak, jak powiedział mvanveen.
Simon Guo
To moja wina. Zapomniałem, że nazwy plików modułów nie mogą zaczynać się od numeru. Opublikowałem zmianę.
mvanveen