У python, як імпортувати ім'я файлу, починається з числа


84

В основному є файл, який називається, 8puzzle.pyі я хочу імпортувати файл в інший файл (в тій же папці, і я не можу змінити ім'я файлу, оскільки файл надається). Чи можна це робити в Python? Я спробував звичайним способом from 8puzzle import *, це видає мені помилку.

Помилка:

>>> import 8puzzle
  File "<input>", line 1
    import 8puzzle
           ^
SyntaxError: invalid syntax
>>> 

12
Чому люди кажуть "це дає мені [помилку]", а потім не публікують помилку?
Джон Цвінк,

7
@JohnZwinck Це синтаксична помилка. Я здогадуюсь, оскільки "8puzzle" не є дійсним ідентифікатором (він починається з числа), а синтаксис оператора import очікує там ідентифікатор Python. Що дасть відповідь "Ні, ви не можете. Перейменуйте модуль на те, що починається з букви або підкреслення".
milimoose

Джон зробив добру думку, я пам’ятаю. І дякую Abhijeet, додайте мені повідомлення про помилку. Дякую.
Simon Guo

1
Перейменуйте 8puzzle.pyна puzzle8.pyта використовуйте import puzzle8.
Бакуріу

Відповіді:


96

Ви могли б це зробити

puzzle = __import__('8puzzle')

Дуже цікава проблема. Я пам’ятатиму, що нічого не називав номером.

Якщо ви хочете import *- вам слід перевірити це питання та відповісти .


1
чудово працює! Дякую. так, я б не називав, що це починається з числа, але це файл роздаткового матеріалу курсу, тому я не можу змінити ім'я. Але, схоже, це не має значення, оскільки ми вже отримали рішення для цього. Знову дякую.
Simon Guo

4
Допоможіть врятувати світ або принаймні своїх однокласників. Якщо вам вручають неможливий імпорт, зверніть на це увагу інструктора. Так, іноді вони ненавидять помилятися, але якщо у вас така проблема, як і всі інші, і хоча ця відповідь працює, це не правильне рішення (якщо клас не "Заплутаний Python 101").
msw

1
Кращий спосіб (принаймні з python 2.7) - використовувати модуль 'importlib': puzzle = importlib.import_module ('8puzzle')
Cédric

3
Для цього насправді є хороший варіант використання - як частина процесу компіляції / виробництва, об’єднання модулів python разом найпростіше, якщо вони названі у лексиграфічній формі (як правило, це не має значення, але константи та імпорт у верхній частині, якщо назва 'внизу, тому кілька модулів, які починаються з' 0 ', можуть бути корисними.) Також корисно для налагодження такого незвичного макета каталогів, у поєднанні з inotify або watch, щось на зразок: watch -n .1' cat * | python ', який завантажував би вашу програму python кожні десяті секунди (або принаймні якомога швидше), або: cat $ (find. -name "* .py") | python
fatal_error

1
Пізно на вечірку, але ще один варіант використання - імпорт з міграцій алембів, оскільки всі вони починаються з випадкових хешів
kevlarr,

35

Наведені вище відповіді правильні, але наразі рекомендованим способом є використання import_moduleфункції:

importlib.import_module(name, package=None)
Імпортуйте модуль. Аргумент name вказує, який модуль імпортувати в абсолютному або відносному вираженні (наприклад, або pkg.modабо ..mod). Якщо ім'я вказано у відносних термінах, тоді аргументу пакета потрібно встановити ім'я пакета, яке повинно виконувати роль якоря для розв'язання імені пакета (наприклад import_module('..mod', 'pkg.subpkg'), імпортуватиме pkg.mod).

Функція import_module () діє як спрощуюча обгортка навколо importlib.__import__(). Це означає, що вся семантика функції похідна importlib.__import__(). Найважливіша різниця між цими двома функціями полягає в тому, що import_module()повертає вказаний пакет або модуль (наприклад pkg.mod), тоді як __import__()повертає пакет або модуль верхнього рівня (наприклад pkg).

Якщо ви динамічно імпортуєте модуль, який був створений з моменту початку інтерпретатора (наприклад, створив вихідний файл Python), можливо, вам доведеться зателефонувати, invalidate_caches()щоб новий модуль був помічений системою імпорту.

__import__ зараз не рекомендується.

importlib.__import__(name, globals=None, locals=None, fromlist=(), level=0)
Реалізація вбудованої __import__()функції.

Примітка. import_module()Замість цієї функції слід використовувати програмний імпорт модулів .


Це справді працює, але це не спрацьовує, щоб імпортувати функцію або змінну всередині одного з цих файлів, починаючи з числа. Якщо я:, an_imported_file = importlib.import_module('13_file')то я не можу from an_imported_file import var_x. Чи можна щось зробити для цього?
Мартін

/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'
Мартін

Крім того, рядок `з an_imported_file import var_x` у Pycharm підкреслено червоним ...
Мартін,

Не знаю шкода. Моя загальна порада - уникати цього.
laike9m

0

Не використовуйте .pyрозширення під час імпорту.

Працює from 8puzzle import *?

Наскільки це варте, from x import *це не бажаний шаблон Python, оскільки він зміщує простір імен цього модуля у ваш поточний контекст.

Загалом, спробуйте імпортувати речі, які ви конкретно хочете від цього модуля. Можна імпортувати будь-який глобальний з іншого модуля.

наприклад, якщо у вас є, 8puzzle.fooви можете зробити `з 8puzzle import

Редагувати:

Хоча моє .pyповідомлення правильне, воно недостатнє.

__import__('8puzzle')Припущення іншого плаката є правильним. Однак я настійно рекомендую уникати цієї моделі .

З одного боку, це зарезервований внутрішній, приватний метод Python. Ви в основному порушуєте основні припущення щодо того, що означає можливість імпортувати модуль. Просто перейменування файлу на щось інше, наприклад puzzle8, виправить це.

Це погіршить досвідчених програмістів Python, які очікують знати, що ваш імпорт знаходиться вгорі, і очікують, що код (спробує) відповідати PEP8 .


1
вибачте за заплутане. Те, що я зробив, було, from 8puzzle import *і я відредагував своє оригінальне запитання. І це не працює, як сказав mvanveen.
Simon Guo

Це моє погане. Я забув, що імена файлів модулів не можуть починатися з числа. Я опублікував редагування.
mvanveen
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.