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

时间:2021-05-02 00:29:30

I wonder if is there any reliable and consistant way to get a Python package's "import name" / namespace. For example;

我想知道是否有任何可靠和一致的方法可以获得Python包的“导入名称”/名称空间。例如;

Package; django-haystack
Import name; haystack

包;django-haystack导入名称;干草堆

or

Package; ipython
Import name; IPython

包;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.

我还尝试自动下载包、提取它并挖掘. egginfo文件,但是有些包根本没有这个文件夹。

Any help will be appreciated and will be used for a good-manner gadget :)

如有任何帮助,我们将感激不尽,并将用于一个友好的小玩意:)

3 个解决方案

#1


0  

Note that what you call a package here is not a package but a distribution. A distribution can contain zero or modules 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文件检查文件系统的更改。

#2


3  

In principal, everything you need to get that information is in the setup.py that is supposed to be in every such package. That information would roughly be the union of the packages, py_modules, ext_package and ext_modules of the Distribution object. In fact, here's a little script that mocks out distutils.core.setup just for the purpose of getting that information.

在principal中,你需要的所有信息都在设置中。这应该在每个这样的包裹里。这些信息大致是分布对象的包、py_modules、ext_package和ext_modules的联合。事实上,这里有一个小脚本可以模拟distutil .core。设置只是为了获取信息。

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,而且我看不到明显的方法。

#3


3  

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.

我知道这是一个古老的问题,但是*包已经被发明了!因为一个*只是一个zip文件,它被提取到lib/站点包目录中,对车轮存档的内容进行检查可以使您获得*的导入。

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

So setuptools actually gives you three top level imports!

setuptools实际上提供了三个*导入!

pip download

pip now has a download command, so you can simply pip download setuptools (or whatever package you like) and then examine it.

pip现在有一个下载命令,所以您只需pip下载setuptools(或您喜欢的任何包),然后检查它。

Reverse look up

Unfortunately I haven't found an easy way to go the other 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,并希望知道实际的包名,那么这可能是一个问题。

#1


0  

Note that what you call a package here is not a package but a distribution. A distribution can contain zero or modules 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文件检查文件系统的更改。

#2


3  

In principal, everything you need to get that information is in the setup.py that is supposed to be in every such package. That information would roughly be the union of the packages, py_modules, ext_package and ext_modules of the Distribution object. In fact, here's a little script that mocks out distutils.core.setup just for the purpose of getting that information.

在principal中,你需要的所有信息都在设置中。这应该在每个这样的包裹里。这些信息大致是分布对象的包、py_modules、ext_package和ext_modules的联合。事实上,这里有一个小脚本可以模拟distutil .core。设置只是为了获取信息。

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,而且我看不到明显的方法。

#3


3  

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.

我知道这是一个古老的问题,但是*包已经被发明了!因为一个*只是一个zip文件,它被提取到lib/站点包目录中,对车轮存档的内容进行检查可以使您获得*的导入。

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

So setuptools actually gives you three top level imports!

setuptools实际上提供了三个*导入!

pip download

pip now has a download command, so you can simply pip download setuptools (or whatever package you like) and then examine it.

pip现在有一个下载命令,所以您只需pip下载setuptools(或您喜欢的任何包),然后检查它。

Reverse look up

Unfortunately I haven't found an easy way to go the other 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,并希望知道实际的包名,那么这可能是一个问题。