Как найти "имя импорта" любого пакета в Python?
Интересно, существует ли какой-либо надежный и последовательный способ получить пакетное имя или пространство имен Python. Например:
Пакет; django-haystack
Имя импорта; стог
или
Пакет; ipython
Имя импорта; IPython
До сих пор я знаю, PyPi не сохраняет эту информацию, которую я проверил с PyPiXmlRpc.
Я также попытался автоматизировать загрузку пакета, извлечь его и скопировать .egg-info, но некоторые пакеты вообще не имеют этой папки.
Любая помощь будет оценена и будет использоваться для гаджета хорошего качества:)
Ответы
Ответ 1
Обратите внимание, что вы называете пакет здесь не пакетом, а дистрибутивом. Распределение может содержать нулевые модули или модули модулей. Это означает, что нет взаимно однозначного сопоставления дистрибутивов пакетам.
Я не уверен, что есть способ определить, какие модули и пакеты будут установлены дистрибутивом, отличным от фактического его установки и внесения изменений в файловую систему для новых пакетов, модулей и файлов pth.
Ответ 2
Колеса
Я знаю, что это старый вопрос, но с тех пор были изобретены колеса ! Поскольку колесо - это просто zip файл, который извлекается в каталог lib/site-packages, проверка содержимого архива колеса может дать вам импорт верхнего уровня.
>>> import zipfile
>>> zf = zipfile.ZipFile('setuptools-35.0.2-py2.py3-none-any.whl')
>>> top_level = set([x.split('/')[0] for x in zf.namelist()])
>>> # filter out the .dist-info directory
>>> top_level = [x for x in top_level if not x.endswith('.dist-info')]
>>> top_level
['setuptools', 'pkg_resources', 'easy_install.py']
Таким образом, setuptools дает вам три импорта верхнего уровня!
скачать pip
Теперь у pip есть команда загрузки, так что вы можете просто запустить pip download setuptools
(или любой другой пакет, который вам нравится), а затем изучить его.
Обратный взгляд вверх
К сожалению, я еще не нашел простой способ пойти в другом направлении. То есть, с учетом имени импорта, каково имя пакета. Это может быть проблемой, если вы смотрите какой-то пример кода или, может быть, если вы используете Anaconda, которая поставляется с кучей предварительно установленных пакетов, и вы хотите знать фактическое имя пакета.
Ответ 3
В принципе, все, что вам нужно для получения этой информации, находится в setup.py
, который должен находиться в каждом таком пакете. Эта информация будет грубо представлять собой объединение пакетов, py_modules, ext_package и ext_modules объекта Distribution. На самом деле, здесь немного script, который издевается distutils.core.setup
только для получения этой информации.
import distutils.core
distutils.core._setup_stop_after = "config"
_real_setup = distutils.core.setup
def _fake_setup(*args, **kwargs):
global dist
dist = _real_setup(*args, **kwargs)
distutils.core.setup = _fake_setup
import sys
setup_file = sys.argv[1]
sys.argv[:] = sys.argv[1:]
import os.path
os.chdir(os.path.dirname(setup_file))
execfile(os.path.basename(setup_file))
cat = lambda *seq: sum((i for i in seq if i is not None), [])
pkgs = set(package.split('.')[0] for package
in cat(dist.packages,
dist.py_modules,
[m.name for m in cat(dist.ext_modules)],
[m.name for m in cat(dist.ext_package)]))
print "\n".join(pkgs)
Для многих пакетов это будет работать как шарм, но для контрпримера см. numpy
. Он ломается, потому что numpy предоставляет свои собственные distutils, и я не вижу очевидного пути вокруг него.