簡體   English   中英

如何在 Python 中找到任何 package 的“導入名稱”?

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

我想知道是否有任何可靠且一致的方法來獲取 Python 包的“導入名稱”/命名空間。 例如;

Package ; django-haystack
導入名稱 草垛

或者

Package ; ipython
導入名稱 IPython

到目前為止我知道,PyPi 不存儲我用 PyPiXmlRpc 檢查過的信息。

我還嘗試自動下載 package,將其解壓縮並挖掘 .egg-info,但有些軟件包根本沒有該文件夾。

任何幫助將不勝感激,並將用於禮貌的小工具:)

輪子

我知道這是一個老問題,但是輪子包已經被發明了! 由於輪子只是一個解壓到 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']

所以 setuptools 實際上為您提供了三個頂級導入!

點子下載

pip 現在有一個下載命令,所以你可以簡單地運行pip download setuptools (或任何你喜歡的包)然后檢查它。

反向查找

不幸的是,我還沒有找到一個簡單的方法去另一個方向。 也就是說,給定導入名稱,包名稱是什么。 如果您正在查看一些示例代碼,或者如果您使用預裝了一堆軟件包的 Anaconda 並且您想知道實際的軟件包名稱,這可能是一個問題。

請注意,這里所說的包不是包而是發行版 一個發行版可以包含零個或多個模塊或包。 這意味着分發到包沒有一對一的映射。

我不確定有沒有一種方法可以檢測發行版將安裝哪些模塊和包,除了實際安裝它並檢查新添加的包、模塊和 pth 文件的文件系統更改。

原則上,獲取該信息所需的一切都在setup.py ,它應該在每個此類包中。 該信息大致是 Distribution 對象的包、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 ,我看不出明顯的解決方法。

在搜索了大量信息之后,終於找到了唯一對我有用的東西。 具有dotenv導入名稱的python-dotenv package 示例:

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

(取自這個答案

我的項目johnnydep具有以下功能:

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

請注意,一個發行版可能會提供多個導入名稱:

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

或者根本沒有:

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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM