简体   繁体   English

如何在 Python 中找到任何 package 的“导入名称”?

[英]How to find "import name" of any package in Python?

I wonder if is there any reliable and consistant way to get a Python package's "import name" / namespace.我想知道是否有任何可靠且一致的方法来获取 Python 包的“导入名称”/命名空间。 For example;例如;

Package ; Package ; django-haystack django-haystack
Import name ;导入名称 haystack草垛

or或者

Package ; Package ; ipython ipython
Import name ;导入名称 IPython IPython

So far I know, PyPi doesn't store that information that I've checked with PyPiXmlRpc.到目前为止我知道,PyPi 不存储我用 PyPiXmlRpc 检查过的信息。

I also tried to automate to download the package, extract it and dig the.egg-info but some packages doesn't have that folder at all.我还尝试自动下载 package,将其解压缩并挖掘 .egg-info,但有些软件包根本没有该文件夹。

Any help will be appreciated and will be used for a good-manner gadget:)任何帮助将不胜感激,并将用于礼貌的小工具:)

Wheels轮子

I know this is an old question, but wheel packages have since been invented!我知道这是一个老问题,但是轮子包已经被发明了! Since a wheel is simply a zip file that gets extracted into the lib/site-packages directory, an examination of the contents of the wheel archive can give you the top level imports.由于轮子只是一个解压到 lib/site-packages 目录中的 zip 文件,因此检查轮子存档的内容可以为您提供顶级导入。

>>> 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']

So setuptools actually gives you three top level imports!所以 setuptools 实际上为您提供了三个顶级导入!

pip download点子下载

pip now has a download command, so you can simply run pip download setuptools (or whatever package you like) and then examine it. pip 现在有一个下载命令,所以你可以简单地运行pip download setuptools (或任何你喜欢的包)然后检查它。

Reverse look up反向查找

Unfortunately I haven't found an easy way to go the other direction yet.不幸的是,我还没有找到一个简单的方法去另一个方向。 That is, given the import name, what is the package name.也就是说,给定导入名称,包名称是什么。 This can be a problem if you are looking at some example code or maybe if you use Anaconda that comes with a bunch of packages pre-installed and you want to know the actual package name.如果您正在查看一些示例代码,或者如果您使用预装了一堆软件包的 Anaconda 并且您想知道实际的软件包名称,这可能是一个问题。

Note that what you call a package here is not a package but a distribution .请注意,这里所说的包不是包而是发行版 A distribution can contain zero or more modules or packages.一个发行版可以包含零个或多个模块或包。 That means there is no one-to-one mapping of distributions to packages.这意味着分发到包没有一对一的映射。

I'm not sure there is a way to detect what modules and packages will be installed by a distribution, other than actually installing it and introspect filesystem changes for newly added packages, modules and pth files.我不确定有没有一种方法可以检测发行版将安装哪些模块和包,除了实际安装它并检查新添加的包、模块和 pth 文件的文件系统更改。

In principal, everything you need to get that information is in the setup.py that is supposed to be in every such package.原则上,获取该信息所需的一切都在setup.py ,它应该在每个此类包中。 That information would roughly be the union of the packages, py_modules, ext_package and ext_modules of the Distribution object.该信息大致是 Distribution 对象的包、py_modules、ext_package 和 ext_modules 的联合。 In fact, here's a little script that mocks out distutils.core.setup just for the purpose of getting that information.事实上,这里有一个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)

For many packages, this will work like a charm, but for a counterexample, see numpy , It breaks because numpy provides its own distutils , and I can see no obvious way around it.对于许多包,这将起到很好的作用,但对于反例,请参阅numpy ,它会中断,因为 numpy提供了自己的 distutils ,我看不出明显的解决方法。

After searching lots of information, finally found the only thing which worked for me as expected.在搜索了大量信息之后,终于找到了唯一对我有用的东西。 Example for python-dotenv package which has dotenv import name:具有dotenv导入名称的python-dotenv package 示例:

$ cat $(python -c "import pkg_resources; print(pkg_resources.get_distribution('python-dotenv').egg_info)")/top_level.txt
dotenv

(taken from this answer ) (取自这个答案

My project johnnydep has this feature:我的项目johnnydep具有以下功能:

>>> from johnnydep import JohnnyDist
>>> dist = JohnnyDist("django-haystack")
>>> dist.import_names
['haystack']

Do note that a distribution may provide multiple import names:请注意,一个发行版可能会提供多个导入名称:

>>> JohnnyDist("setuptools").import_names
['pkg_resources', 'setuptools']

or none at all:或者根本没有:

>>> JohnnyDist("bs4").import_names
[]

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM