Имя модуля отличается от имени каталога?

Предположим, у меня есть пакет Python с именем bestpackage.

Соглашение диктует, что bestpacakge также будет каталогом на sys.path, который содержит __init__.py, чтобы интерпретатор предположил, что он может быть импортирован.

Есть ли способ установить переменную для имени пакета, чтобы каталог можно было назвать иначе, чем директива, с которой я его импортирую? Есть ли способ сделать так, чтобы пространство имен не заботилось о имени каталога и вместо этого учитывало какую-то другую конфигурацию?

Мои супермодные клиентские разработчики просто в восторге от этих something.otherthing.js сексуальных названий проектов для одного из наших небольших сторонних проектов!

ИЗМЕНИТЬ:

Чтобы уточнить, основная цель моего вопроса заключалась в том, чтобы позволить моим парням на стороне клиента продолжать вызывать каталоги в своих папках «проекты» (тот, который мы все добавили к нашим путям), используя их существующее соглашение (some.app.js), даже несмотря на то, что в некоторых случаях они на самом деле являются пакетами Python, которые будут находиться на пути и исходить из операторов import внутри. Я понимаю, что на практике это довольно ужасная вещь, и поэтому я спрашиваю больше из любопытства. Таким образом, часть большой проблемы здесь заключается в том, чтобы обойти тот факт, что . в имени каталога (и, следовательно, в предполагаемом имени пакета) подразумевает доступ к атрибуту. Меня не очень удивляет, что это нельзя обойти, мне просто любопытно, возможно ли это глубже в «магии» импорта.

Здесь есть несколько замечательных ответов, но все они основаны на выполнении классического импорта, в котором метод доступа к атрибуту . будет конфликтовать с именами каталогов.


person DeaconDesperado    schedule 06.11.2012    source источник
comment
Каталог с файлом __init__.py называется пакетом.   -  person Martijn Pieters    schedule 06.11.2012
comment
Спасибо, я всегда путаю эти термины. Буду редактировать.   -  person DeaconDesperado    schedule 06.11.2012


Ответы (5)


Каталог с файлом __init__.py называется пакетом.

И нет, имя пакета всегда совпадает с именем каталога. Вот как Python может обнаруживать пакеты, он сопоставляет их с именами каталогов, найденными на пути поиска, и, если в этом каталоге есть файл __init__.py, он находит совпадение и импортирует содержащийся файл __init__.py.

Вы всегда можете импортировать что-то в пространство имен вашего локального модуля под более коротким и простым в использовании именем, используя синтаксис from module import something или import module as alias:

from something.otherthing.js import foo
from something.otherthing import js as bar
import something.otherthing.js as hamspam
person Martijn Pieters    schedule 06.11.2012
comment
Кстати, всегда можно сделать import X as Y. Таким образом, вы должны вызывать каталог X, но вы можете ссылаться на него как на Y в коде. (Может быть, этого достаточно для ОП?) - person Bakuriu; 06.11.2012
comment
@Bakuriu: да, во втором чтении (отредактированном?), Вероятно, это то, чего хочет ОП в любом случае. Обновлено. - person Martijn Pieters; 06.11.2012
comment
Возможно, я не совсем понял это ... основная проблема здесь - синхронизация множества локально запущенных приложений фляг, которые являются пакетами. Система представляет собой API на стороне клиента, который имеет серверную часть в flask, поэтому все мои клиентские разработчики назвали свои каталоги чем-то вроде «the.project.js», поскольку это типичная вещь, которую они делают со своими проектами. Это, конечно, большая проблема для интерпретатора Python, когда он обрабатывает их как пакеты. - person DeaconDesperado; 07.11.2012

Есть одно решение, которое где-то нуждается в одном начальном импорте

>>> import sys
>>> sys.modules['blinot_existing_blubb'] = sys
>>> import blinot_existing_blubb
>>> blinot_existing_blubb
<module 'sys' (built-in)>

Без изменения механизма импорта вы не можете импортировать с другого имени. Я думаю, это сделано для того, чтобы упростить понимание Python.

Однако, если вы хотите изменить механизм импорта, я рекомендую следующее: Получить максимальную отдачу от импорта Python

person User    schedule 06.11.2012

Ну, во-первых, я бы сказал, что Python is not Java/Javascript/C/C++/Cobol/YourFavoriteLanguageThatIsntPython. Конечно, в реальном мире некоторым из нас приходится отвечать перед боссами, которые не согласны. Так что, если все, что вам нужно, это некоторая косвенность, используйте дым и зеркала, пока они не уделяют слишком много внимания тому, что находится под капотом. Напишите свой модуль в стиле Python, а затем предоставьте API на стороне в точечном стиле, который нужен вашим коллегам. Бывший:

pythonic_module.py

def func_1():
    pass

def func_2():
    pass

def func_3():
    pass

def func_4():
    pass

indirection

/dotty_api_1/__init__.py

from pythonic_module import func_1 as foo, func_2 as bar

/dotty_api_2/__init__.py

from pythonic_module import func_3 as foo, func_4 as bar

Теперь они могут сколько угодно расставлять точки, но вы можете писать что-то по-питоновски под капотом.

person Silas Ray    schedule 06.11.2012

На самом деле да! вы могли бы сделать канонический import Whatever или newmodulename = __import__("Whatever")

python отслеживает ваши модули, и вы можете проверить это, выполнив:

import sys
print sys.modules

Дополнительные сведения см. в этой статье.

Но может это не твоя проблема? давайте предположим: у вас есть модуль по другому пути, к которому ваш текущий проект не может получить доступ, потому что он не находится в sys-пути?

ну просто добавь:

import sys
sys.path.append('path_to_the_other_package_or_module_directory')

до вашего заявления import или см. этот SO-post для более постоянного решения .

person Don Question    schedule 06.11.2012

Я искал, чтобы это произошло с setup.py в sdist и во время установки, а не во время выполнения, и нашел директиву package_dir:

person Gringo Suave    schedule 25.06.2017