Можно ли использовать тире в файлах Python при их импорте?

154

В основном, когда у меня есть файл Python, например:

python-code.py

и используйте:

import (python-code)

интерпретатор дает мне синтаксическую ошибку.

Есть идеи, как это исправить? Являются ли дефисы незаконными в именах файлов Python?

Джоан Венге
источник

Ответы:

174

Вам следует ознакомиться с PEP 8 , Руководством по стилю для кода Python:

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

Поскольку имена модулей сопоставляются с именами файлов, а некоторые файловые системы нечувствительны к регистру и обрезают длинные имена, важно, чтобы имена модулей были достаточно короткими - это не будет проблемой в Unix, но может быть проблема, когда код переносится на старые версии Mac, Windows или DOS.

Другими словами: переименуйте файл :)

Паоло Бергантино
источник
78
проблема не связана со стилем, это синтаксическая ошибка
4
Как показано ниже, файл с таким именем все еще может существовать, поэтому руководство по стилю очень актуально.
Паоло Бергантино
5
Может быть очень полезно использовать дефисы в каталогах Python и именах файлов, если вы явно хотите запретить импорт. Например, в (скажем) проекте Django у вас могут быть сценарии, написанные на Python, которые нельзя использовать как приложения. Вы можете поместить их в папку, например, ops-scriptsи знать, что они не могут быть импортированы с использованием обычного подхода к пространству имен пакетов. Или один сценарий может быть назван stop-website.pyдля аналогичного эффекта. runpyКонечно, любой из них можно импортировать с помощью и некоторыми другими методами, но это помогает избежать некоторых распространенных ошибок.
Крис Джонсон,
Переименование модуля может быть проблематичным, особенно если вы полагаетесь на другой стандарт. В моем случае я использую файлы cgi python в cgi-binпапке (выполняя для них unitttests), что довольно стандартно для afaik. Если у вас нет такого редкого случая, обязательно переименуйте свой модуль, если вы контролируете его.
NuclearPeon 09
1
Я только что обнаружил, что PyDev разрешает имена каталогов с дефисами, но не будет отображать классы и / или внутренние переменные в файлах .py, которые содержатся в этом каталоге.
user5920660
124

Еще одна вещь, которую следует отметить в вашем коде, заключается в том, что импорт не является функцией. Так import(python-code)должно быть то, import python-codeчто, как уже упоминалось, интерпретируется как «импорт python минус код», а не то, что вы намеревались. Если вам действительно нужно импортировать файл с тире в его имени, вы можете сделать следующее:

python_code = __import__('python-code')

Но, как уже упоминалось выше, это не рекомендуется. Вам следует изменить имя файла, если оно находится под вашим контролем.

Рик Коупленд
источник
@KevinAudleman у вас есть рабочий пример использования import lib с файлом с дефисом? Я пробовал и потерпел неудачу.
Tom Hale
@TomHale importlib.import_module ('abmodule-1') должен работать. Если ваш import_module не работает, я думаю, что обычный импорт также не будет работать.
Ян Линь
66

TL; DR

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

  1. Для импорта файлов с дефисами необходим специальный синтаксис
  2. Никто не ждет имени модуля с тире
  3. Это противоречит рекомендациям Руководства по стилю Python.

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

module_name = __import__('module-name')

Интересно, зачем нам нужен особый синтаксис?

Причина использования специального синтаксиса заключается в том, что при написании import somenameвы создаете объект модуля с идентификатором somename(чтобы позже вы могли использовать его, например somename.funcname). Конечно, module-nameэто недействительный идентификатор и, следовательно, специальный синтаксис, который дает действительный идентификатор.

Вы не понимаете, почему имя модуля не является допустимым идентификатором?

Не волнуйтесь - я тоже. Вот подсказка , чтобы помочь вам: Посмотрите на эту питона линии: x=var1-var2. Вы видите вычитание справа от присваивания или имя переменной с тире?

PS

В моем ответе нет ничего оригинального, за исключением включения того, что я считал наиболее актуальной информацией из всех других ответов в одном месте

Ndemou
источник
Я пытаюсь использовать этот импорт пакета pip с дефисом. psycopg2_binary = import_module('psycopg2-binary'). Ошибка => ModuleNotFoundError: No module named 'psycopg2-binary'. Но psycopg2-binaryустановлен. Не знаю, как это включить.
Mote
Может, это проблема пути. Посмотрите на chrisyeh96.github.io/2017/08/08/…
ndemou 01
32

Проблема в том, что python-codeэто не идентификатор. Парсер видит в этом pythonминус code. Конечно, это не поможет. Вам нужно будет использовать имя файла, которое также является допустимым идентификатором Python. Попробуйте заменить -символ подчеркивания.

SingleNegationElimination
источник
4
+1. Никогда не думал, что имя файла исходного кода Python должно быть допустимым идентификатором, потому что имя файла будет использоваться для ссылки на объект модуля.
Энди
6

Вы, вероятно, могли бы импортировать его с помощью какого-нибудь __import__взлома, но если вы еще не знаете, как, вам не следует этого делать. Имена модулей Python должны быть допустимыми именами переменных («идентификаторами») - это означает, что если у вас есть модуль foo_bar, вы можете использовать его из Python ( print foo_bar). Вы не смогли бы сделать это со странным именем ( print foo-bar-> синтаксическая ошибка).

Джон Милликин
источник
5

В Python 3 используйте import_module :

from importlib import import_module
python_code = import_module('python-code')

В более общем смысле,

import_module('package.subpackage.module')
e18r
источник
1

Хотя правильное именование файлов - лучший вариант, если python-codeэто не находится под нашим контролем, использование взлома __import__лучше, чем копирование, переименование или иным образом возиться с кодом других авторов. Однако я попытался, и это не сработало, если я не переименовал файл, добавив .pyрасширение. Посмотрев на документ, чтобы узнать, как получить описание .py, я пришел к следующему:

import imp

try:
    python_code_file = open("python-code")
    python_code = imp.load_module('python_code', python_code_file, './python-code', ('.py', 'U', 1))
finally:
    python_code_file.close()

Он создал новый файл python-codecпри первом запуске.

Эль
источник