Как найти "import name" любого пакета в Python?

интересно, есть ли надежный и последовательный способ получить "имя импорта" / пространство имен пакета Python. Например:

пакета; Джанго-сена
имя импорт; сена

или

пакета; оболочкой IPython
имя импорт; IPython

пока я знаю, PyPi не хранит эту информацию, которую я проверил с помощью PyPiXmlRpc.

Я также попытался автоматизировать загрузите пакет, извлеките его и копайте.egg-info, Но некоторые пакеты вообще не имеют этой папки.

любая помощь будет оценена и будет использоваться для хорошего гаджета:)

3 ответов


обратите внимание, что то, что вы называете здесь пакет не пакет, а распределение. Дистрибутив может содержать нуль или модули, модули или пакеты. Это означает, что нет однозначного сопоставления распределений пакетам.

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


колеса

Я знаю, это старый вопрос, но колеса пакеты с тех пор были изобретены! Сколеса это просто 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 z.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, который поставляется с кучей предварительно установленных пакетов, и вы хотите знать фактическое имя пакета.


в принципе, все, что вам нужно получить эту информацию в setup.py это должно быть в каждом таком пакете. Эта информация будет грубо Союза пакетов, py_modules, ext_package и ext_modules объекта распределения. На самом деле, вот небольшой сценарий, который издевается 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 и я не вижу очевидного способа вокруг него.