Чи нормально використовувати тире у файлах Python при спробі імпортувати їх?


149

В основному, коли у мене є файл python, наприклад:

python-code.py

і використовувати:

import (python-code)

інтерпретатор видає мені синтаксичну помилку.

Будь-які ідеї, як це виправити? Чи є тире незаконними у назвах файлів python?

Відповіді:


167

Ви повинні ознайомитись з PEP 8 , посібником зі стилю для Python Code:

Імена пакетів та модулів Модулі повинні мати короткі, малі імена. Підкреслення можна використовувати у назві модуля, якщо це покращує читабельність. Пакети Python також повинні мати короткі, малі імена, хоча використання підкреслення не рекомендується.

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

Іншими словами: перейменуйте свій файл :)


75
проблема не має нічого спільного зі стилем, це синтаксична помилка

4
Як показано нижче, все ще можливо мати файл з цим ім'ям, тому посібник зі стилів дуже актуальний.
Паоло Бергантіно

5
Використання дефісів в каталозі Python та імен файлів може бути дуже корисно, коли ви явно хочете запобігти імпорту. Наприклад, у (скажімо,) проект Django, у вас можуть бути написані сценарії на Python, які не повинні бути адресовані як програми. Ви можете помістити їх у папку, як ops-scriptsі знаєте, що їх неможливо імпортувати, використовуючи звичайний підхід до простору імен. Або один сценарій може бути названий stop-website.pyдля подібного ефекту. Будь-який із них все-таки можна імпортувати за допомогою runpyта інших методів, звичайно, але це допомагає уникнути деяких поширених помилок.
Кріс Джонсон

Перейменування модуля може бути проблематичним, особливо якщо ви покладаєтесь на інший стандарт. У моєму випадку я використовую файли cgi python у cgi-binпапці (роблячи на них unitttests), що є досить стандартним afaik. Якщо у вас є такий рідкісний випадок, обов'язково перейменуйте свій модуль, якщо у вас є контроль над ним.
NuclearPeon

1
Я щойно виявив, що PyDev дозволить імена каталогів з дефісами, але не буде показувати класи та / або внутрішні змінні у файлах .py, що містяться в цьому каталозі.
користувач5920660

123

Ще одна річ, яку слід зазначити у вашому коді, це те, що імпорт - це не функція. Так import(python-code)має бути, import python-codeщо, як уже згадувалося, трактується як "імпортувати пітон мінус-код", а не те, що ви задумали. Якщо вам дійсно потрібно імпортувати файл з тире в його імені, ви можете зробити наступне:

python_code = __import__('python-code')

Але, як також було сказано вище, це не дуже рекомендується. Ви повинні змінити ім'я файлу, якщо це щось, чим ви керуєте.


@KevinAudleman, чи є у вас робочий приклад використання імпортної lib з дефісом? Я спробував і не вдався.
Том Хейл

@TomHale importlib.import_module ('abmodule-1') повинен працювати. Якщо ваш import_module не працює, я думаю, що нормальний імпорт також не працюватиме.
Ян Лін

64

TLDR

Дефіси не є незаконними, але не слід їх використовувати з 3 причин:

  1. Вам потрібен спеціальний синтаксис для імпорту файлів з тире
  2. Ніхто не очікує назви модуля з тире
  3. Це проти рекомендацій Посібника зі стилів Python

Якщо вам обов'язково потрібно імпортувати ім'я файлу з тире, спеціальним синтаксисом є такий:

module_name = __import__('module-name')

Цікаво, чому нам потрібен спеціальний синтаксис?

Причина спеціального синтаксису полягає в тому, що коли ви пишете, import somenameви створюєте об'єкт модуля з ідентифікатором somename(щоб потім ви могли його використовувати, наприклад somename.funcname). Звичайно, module-nameце не дійсний ідентифікатор, а отже, і спеціальний синтаксис, який дає дійсний.

Ви не розумієте, чому ім'я модуля не є дійсним ідентифікатором?

Не хвилюйтесь - я теж не став. Ось підказка , щоб допомогти вам: Подивіться на цю пітона лінії: x=var1-var2. Ви бачите віднімання в правій частині завдання або ім'я змінної з тире?

PS

У моїй відповіді немає нічого оригінального, крім того, що я вважав найбільш релевантними фрагментами інформації з усіх інших відповідей в одному місці


Я намагаюся використовувати цей імпорт пакету піп з дефісом у ньому. psycopg2_binary = import_module('psycopg2-binary'). Помилка => ModuleNotFoundError: No module named 'psycopg2-binary'. Але psycopg2-binaryвстановлено. Не маю ідеї, як її включити.
Mote Zart

Можливо, це питання шляху. Подивіться на chrisyeh96.github.io/2017/08/08/…
ndemou

32

Проблема в тому, що python-codeце не ідентифікатор. Парсер розглядає це як pythonмінус code. Звичайно, це не буде робити те, що ви просите. Вам потрібно буде використовувати ім’я файлу, яке також є дійсним ідентифікатором python. Спробуйте замінити -підкреслення.


4
+1. Ніколи не думав, що ім'я файлу вихідного коду Python має бути дійсним ідентифікатором, тому що ім'я файлу буде використовуватися для позначення об'єкта модуля.
Andy

5

Ви, ймовірно, можете імпортувати його через якийсь __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')

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з першого запуску.

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