检查Python包是否安装

发布于 2024-07-25 09:37:51 字数 227 浏览 6 评论 0原文

在 Python 脚本中检查软件包是否已安装的好方法是什么? 我知道这对于解释器来说很容易,但我需要在脚本中完成。

我想我可以检查系统上是否有安装过程中创建的目录,但我觉得有更好的方法。 我正在尝试确保 Skype4Py 软件包已安装,如果没有,我将安装它。

我完成检查

  • 典型安装路径中目录的
  • 想法尝试导入包,如果抛出异常,则安装包

What's a good way to check if a package is installed while within a Python script? I know it's easy from the interpreter, but I need to do it within a script.

I guess I could check if there's a directory on the system that's created during the installation, but I feel like there's a better way. I'm trying to make sure the Skype4Py package is installed, and if not I'll install it.

My ideas for accomplishing the check

  • check for a directory in the typical install path
  • try to import the package and if an exception is throw, then install package

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(21

梦里梦着梦中梦 2024-08-01 09:37:52

在终端类型

pip show some_package_name

示例中

pip show matplotlib

In the Terminal type

pip show some_package_name

Example

pip show matplotlib
清风不识月 2024-08-01 09:37:52

作为这个答案的扩展:

对于Python 2.*,pip show将执行相同的任务。

例如 pip show numpy 将返回以下或类似内容:

Name: numpy
Version: 1.11.1
Summary: NumPy: array processing for numbers, strings, records, and objects.
Home-page: http://www.numpy.org
Author: NumPy Developers
Author-email: [email protected]
License: BSD
Location: /home/***/anaconda2/lib/python2.7/site-packages
Requires: 
Required-by: smop, pandas, tables, spectrum, seaborn, patsy, odo, numpy-stl, numba, nfft, netCDF4, MDAnalysis, matplotlib, h5py, GridDataFormats, dynd, datashape, Bottleneck, blaze, astropy

As an extension of this answer:

For Python 2.*, pip show <package_name> will perform the same task.

For example pip show numpy will return the following or alike:

Name: numpy
Version: 1.11.1
Summary: NumPy: array processing for numbers, strings, records, and objects.
Home-page: http://www.numpy.org
Author: NumPy Developers
Author-email: [email protected]
License: BSD
Location: /home/***/anaconda2/lib/python2.7/site-packages
Requires: 
Required-by: smop, pandas, tables, spectrum, seaborn, patsy, odo, numpy-stl, numba, nfft, netCDF4, MDAnalysis, matplotlib, h5py, GridDataFormats, dynd, datashape, Bottleneck, blaze, astropy
无可置疑 2024-08-01 09:37:52

您可以使用 setuptools 中的 pkg_resources 模块。 例如:

import pkg_resources

package_name = 'cool_package'
try:
    cool_package_dist_info = pkg_resources.get_distribution(package_name)
except pkg_resources.DistributionNotFound:
    print('{} not installed'.format(package_name))
else:
    print(cool_package_dist_info)

请注意,python 模块和 python 包之间存在差异。 一个包可以包含多个模块,并且模块的名称可能与包名称不匹配。

You can use the pkg_resources module from setuptools. For example:

import pkg_resources

package_name = 'cool_package'
try:
    cool_package_dist_info = pkg_resources.get_distribution(package_name)
except pkg_resources.DistributionNotFound:
    print('{} not installed'.format(package_name))
else:
    print(cool_package_dist_info)

Note that there is a difference between python module and a python package. A package can contain multiple modules and module's names might not match the package name.

你怎么敢 2024-08-01 09:37:52
if pip list | grep -q \^'PACKAGENAME\s'
  # installed ...
else
  # not installed ...
fi
if pip list | grep -q \^'PACKAGENAME\s'
  # installed ...
else
  # not installed ...
fi
暮倦 2024-08-01 09:37:52

方法1

使用pip3 list命令搜索包是否存在

#**pip3 list** will display all the packages and **grep** command will search for a particular package
pip3 list | grep your_package_name_here

方法2

可以使用ImportError

try:
    import your_package_name
except ImportError as error:
    print(error,':( not found')

方法3

!pip install your_package_name
import your_package_name
...
...

Method 1

to search weather a package exists or not use pip3 list command

#**pip3 list** will display all the packages and **grep** command will search for a particular package
pip3 list | grep your_package_name_here

Method 2

You can use ImportError

try:
    import your_package_name
except ImportError as error:
    print(error,':( not found')

Method 3

!pip install your_package_name
import your_package_name
...
...
听闻余生 2024-08-01 09:37:52

你可以使用这个:

class myError(exception):
 pass # Or do some thing like this.
try:
 import mymodule
except ImportError as e:
 raise myError("error was occurred")

You can use this:

class myError(exception):
 pass # Or do some thing like this.
try:
 import mymodule
except ImportError as e:
 raise myError("error was occurred")
无戏配角 2024-08-01 09:37:52

我想在这个主题中添加一些我的想法/发现。
我正在编写一个脚本来检查定制程序的所有要求。 python 模块也有很多检查。

解决方案有点问题

try:
   import ..
except:
   ..


就我而言,其中一个名为 python-nmap 的 python 模块,但是您使用 import nmap 导入它,并且您看到名称不匹配。 因此,使用上述解决方案的测试返回 False 结果,并且它还会在命中时导入模块,但可能不需要使用大量内存来进行简单的测试/检查。

我还发现

import pip
installed_packages = pip.get_installed_distributions()

installed_pa​​ckages 将仅包含使用 pip 安装的软件包
在我的系统上,pip freeze 返回超过 40 个 python 模块,而 installed_pa​​ckages 只有 1,即我手动安装的模块(python-nmap)。

下面的另一种解决方案,我知道它可能与问题无关,但我认为将测试功能与执行安装的功能分开是一种很好的做法对某些人有用。

对我有用的解决方案。 它基于这个答案如何检查 python 模块是否存在而不导入它

from imp import find_module

def checkPythonmod(mod):
    try:
        op = find_module(mod)
        return True
    except ImportError:
        return False

注意:此解决方案无法找到该模块也通过名称 python-nmap ,我必须使用 nmap (易于使用),但在这种情况下,模块不会被加载到内存中。

I'd like to add some thoughts/findings of mine to this topic.
I'm writing a script that checks all requirements for a custom made program. There are many checks with python modules too.

There's a little issue with the

try:
   import ..
except:
   ..

solution.
In my case one of the python modules called python-nmap, but you import it with import nmap and as you see the names mismatch. Therefore the test with the above solution returns a False result, and it also imports the module on hit, but maybe no need to use a lot of memory for a simple test/check.

I also found that

import pip
installed_packages = pip.get_installed_distributions()

installed_packages will have only the packages has been installed with pip.
On my system pip freeze returns over 40 python modules, while installed_packages has only 1, the one I installed manually (python-nmap).

Another solution below that I know it may not relevant to the question, but I think it's a good practice to keep the test function separate from the one that performs the install it might be useful for some.

The solution that worked for me. It based on this answer How to check if a python module exists without importing it

from imp import find_module

def checkPythonmod(mod):
    try:
        op = find_module(mod)
        return True
    except ImportError:
        return False

NOTE: this solution can't find the module by the name python-nmap too, I have to use nmap instead (easy to live with) but in this case the module won't be loaded to the memory whatsoever.

驱逐舰岛风号 2024-08-01 09:37:52

我想对 @ice.nicer 回复发表评论,但我不能,所以......
我的观察是,带有破折号的包用下划线保存,而不仅仅是像 @dwich 评论指出的那样用点保存。

例如,您执行 pip3 install sphinx-rtd-theme,但是:

  • importlib. util.find_spec(sphinx_rtd_theme) 返回一个对象
  • importlib.util.find_spec(sphinx-rtd-theme) 返回 None
  • importlib.util.find_spec(sphinx.rtd.theme)< /code> 引发 ModuleNotFoundError

此外,一些名称完全改变了。
例如,您执行 pip3 install pyyaml 但它只是保存为 yaml

我正在使用 python3.8

I would like to comment to @ice.nicer reply but I cannot, so ...
My observations is that packages with dashes are saved with underscores, not only with dots as pointed out by @dwich comment

For example, you do pip3 install sphinx-rtd-theme, but:

  • importlib.util.find_spec(sphinx_rtd_theme) returns an Object
  • importlib.util.find_spec(sphinx-rtd-theme) returns None
  • importlib.util.find_spec(sphinx.rtd.theme) raises ModuleNotFoundError

Moreover, some names are totally changed.
For example, you do pip3 install pyyaml but it is saved simply as yaml

I am using python3.8

故人如初 2024-08-01 09:37:52

如果您希望脚本安装缺少的软件包并继续,您可以执行以下操作(以“python-krbV”软件包中的“krbV”模块为例):

import pip
import sys

for m, pkg in [('krbV', 'python-krbV')]:
    try:
        setattr(sys.modules[__name__], m, __import__(m))
    except ImportError:
        pip.main(['install', pkg])
        setattr(sys.modules[__name__], m, __import__(m))

If you'd like your script to install missing packages and continue, you could do something like this (on example of 'krbV' module in 'python-krbV' package):

import pip
import sys

for m, pkg in [('krbV', 'python-krbV')]:
    try:
        setattr(sys.modules[__name__], m, __import__(m))
    except ImportError:
        pip.main(['install', pkg])
        setattr(sys.modules[__name__], m, __import__(m))
秋风の叶未落 2024-08-01 09:37:52

一种快速的方法是使用python命令行工具。
只需输入 import <您的模块名称>
如果模块丢失,您会看到错误。

$ python
Python 2.7.6 (default, Jun 22 2015, 17:58:13) 
>>> import sys
>>> import jocker
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ImportError: No module named jocker
$

A quick way is to use python command line tool.
Simply type import <your module name>
You see an error if module is missing.

$ python
Python 2.7.6 (default, Jun 22 2015, 17:58:13) 
>>> import sys
>>> import jocker
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ImportError: No module named jocker
$
走野 2024-08-01 09:37:52

嗯...我看到的最接近方便的答案是使用命令行来尝试导入。 但我什至更愿意避免这种情况。

'pip freeze | 怎么样? grep pkgname'? 我尝试了一下,效果很好。 它还向您显示它的版本以及它是在版本控制(安装)还是可编辑(开发)下安装的。

Hmmm ... the closest I saw to a convenient answer was using the command line to try the import. But I prefer to even avoid that.

How about 'pip freeze | grep pkgname'? I tried it and it works well. It also shows you the version it has and whether it is installed under version control (install) or editable (develop).

疯到世界奔溃 2024-08-01 09:37:52

我一直使用 pylibcheck 来检查库是否已安装,只需通过执行以下操作即可下载它pip install pylibcheck 可能是这样的,

import pylibcheck

if not pylibcheck.checkPackage("mypackage"):
     #not installed

它还支持元组和列表,因此您可以检查多个包,如果它们已安装,

import pylibcheck

packages = ["package1", "package2", "package3"]

if pylibcheck.checkPackage(packages):
     #not installed

您也可以使用它安装库(如果您想这样做),建议您查看官方 pypi

I've always used pylibcheck to check if a lib is installed or not, simply download it by doing pip install pylibcheck and the could could be like this

import pylibcheck

if not pylibcheck.checkPackage("mypackage"):
     #not installed

it also supports tuples and lists so you can check multiple packages and if they are installed or not

import pylibcheck

packages = ["package1", "package2", "package3"]

if pylibcheck.checkPackage(packages):
     #not installed

you can also install libs with it if you want to do that, recommend you check the official pypi

最后的乘客 2024-08-01 09:37:52

投票最高的解决方案使用 importlib.util.find_specsys.modules 等技术并捕获导入异常,适用于大多数包,但在某些边缘情况下会失败(例如 < code>beautifulsoup 包),其中导入中使用的包名称与安装文件配置中使用的包名称有些不同(在本例中为 bs4)。 对于这些边缘情况,除非您传递导入中使用的包名称而不是 requirements.txtpip 安装中使用的包名称,否则此解决方案不起作用。

对于我的用例,我需要编写一个包检查器来根据 requirements.txt 检查已安装的包,因此该解决方案不起作用。 我最终使用的是 subprocess.check 显式调用 pip 模块来检查包安装:

import subprocess

for pkg in packages:
    try:
        subprocess.check_output('py -m pip show ' + pkg)
    except subprocess.CalledProcessError as ex:
        not_found.append(pkg)

它比其他方法慢一点,但更可靠并且可以处理边缘情况。

The top voted solution which uses techniques like importlib.util.find_spec and sys.modules and catching import exceptions works for most packages but fails in some edge cases (such as the beautifulsoup package) where the package name used in imports is somewhat different (bs4 in this case) than the one used in setup file configuration. For these edge cases, this solution doesn't work unless you pass the package name used in imports instead of the one used in requirements.txt or pip installations.

For my use case, I needed to write a package checker that checks installed packages based on requirements.txt, so this solution didn't work. What I ended up using was subprocess.check to call the pip module explicitly to check for the package installation:

import subprocess

for pkg in packages:
    try:
        subprocess.check_output('py -m pip show ' + pkg)
    except subprocess.CalledProcessError as ex:
        not_found.append(pkg)

It's a bit slower than the other methods but more reliable and handles the edge cases.

薔薇婲 2024-08-01 09:37:52

虽然并不完美,但以下解决方案通常比 pip show ... 快得多,并且也适用于多个包

_pip_install() {
    installed_packages=$(pip freeze)

    for PACKAGE in "$@"; do
        if echo "$installed_packages" | grep "^${PACKAGE}=="; then
            true
        else
            echo "Installing $PACKAGE..."
            pip install "$PACKAGE"
        fi
    done
}

While not perfect, the following solution is usually much quicker than pip show ... and also works for multiple packages

_pip_install() {
    installed_packages=$(pip freeze)

    for PACKAGE in "$@"; do
        if echo "$installed_packages" | grep "^${PACKAGE}=="; then
            true
        else
            echo "Installing $PACKAGE..."
            pip install "$PACKAGE"
        fi
    done
}
一个人的旅程 2024-08-01 09:37:52

选择选项#2。 如果抛出 ImportError ,则说明该包未安装(或不在 sys.path 中)。

Go option #2. If ImportError is thrown, then the package is not installed (or not in sys.path).

时光倒影 2024-08-01 09:37:52

有机会使用下面给出的片段吗? 当我运行此代码时,它返回“模块 pandas 未安装”

a = "pandas"

try:
    import a
    print("module ",a," is installed")
except ModuleNotFoundError:
    print("module ",a," is not installed")

但是当我运行下面给出的代码时:

try:
    import pandas
    print("module is installed")
except ModuleNotFoundError:
    print("module is not installed")

它返回“模块 pandas 已安装”。

它们之间有什么区别?

Is there any chance to use the snippets given below? When I run this code, it returns "module pandas is not installed"

a = "pandas"

try:
    import a
    print("module ",a," is installed")
except ModuleNotFoundError:
    print("module ",a," is not installed")

But when I run the code given below:

try:
    import pandas
    print("module is installed")
except ModuleNotFoundError:
    print("module is not installed")

It returns "module pandas is installed".

What is the difference between them?

紫南 2024-08-01 09:37:51

如果您指的是 python 脚本,只需执行以下操作:

Python 3.3+ use sys.modules and find_spec

import importlib.util
import sys

# For illustrative purposes.
name = 'itertools'

if name in sys.modules:
    print(f"{name!r} already in sys.modules")
elif (spec := importlib.util.find_spec(name)) is not None:
    # If you choose to perform the actual import ...
    module = importlib.util.module_from_spec(spec)
    sys.modules[name] = module
    spec.loader.exec_module(module)
    print(f"{name!r} has been imported")
else:
    print(f"can't find the {name!r} module")

Python 3:

try:
    import mymodule
except ImportError as e:
    pass  # module doesn't exist, deal with it.

Python 2:

try:
    import mymodule
except ImportError, e:
    pass  # module doesn't exist, deal with it.

If you mean a python script, just do something like this:

Python 3.3+ use sys.modules and find_spec:

import importlib.util
import sys

# For illustrative purposes.
name = 'itertools'

if name in sys.modules:
    print(f"{name!r} already in sys.modules")
elif (spec := importlib.util.find_spec(name)) is not None:
    # If you choose to perform the actual import ...
    module = importlib.util.module_from_spec(spec)
    sys.modules[name] = module
    spec.loader.exec_module(module)
    print(f"{name!r} has been imported")
else:
    print(f"can't find the {name!r} module")

Python 3:

try:
    import mymodule
except ImportError as e:
    pass  # module doesn't exist, deal with it.

Python 2:

try:
    import mymodule
except ImportError, e:
    pass  # module doesn't exist, deal with it.
隔岸观火 2024-08-01 09:37:51

从 Python 3.3 开始,您可以使用 find_spec() 方法

import importlib.util

# For illustrative purposes.
package_name = 'pandas'

spec = importlib.util.find_spec(package_name)
if spec is None:
    print(package_name +" is not installed")

As of Python 3.3, you can use the find_spec() method

import importlib.util

# For illustrative purposes.
package_name = 'pandas'

spec = importlib.util.find_spec(package_name)
if spec is None:
    print(package_name +" is not installed")
情深已缘浅 2024-08-01 09:37:51

更新的答案

更好的方法是:

import subprocess
import sys

reqs = subprocess.check_output([sys.executable, '-m', 'pip', 'freeze'])
installed_packages = [r.decode().split('==')[0] for r in reqs.split()]

结果:

print(installed_packages)

[
    "Django",
    "six",
    "requests",
]

检查是否安装了请求:

if 'requests' in installed_packages:
    # Do something

为什么这样? 有时您会遇到应用程序名称冲突的情况。 从应用程序命名空间导入并不能让您全面了解系统上安装的内容。

请注意,建议的解决方案有效:

  • 当使用 pip 从 PyPI 或任何其他替代源安装时(例如 pip install http://some.site/package-name.zip 或任何其他存档类型) 。
  • 使用 python setup.py install 手动安装时。
  • 从系统存储库安装时,例如 sudo apt install python-requests 。

它可能无法工作的情况:

  • 在开发模式下安装时,例如python setup.pydevelop
  • 在开发模式下安装时,例如pip install -e /path/to/package/source/

旧答案

更好的方法是:

import pip
installed_packages = pip.get_installed_distributions()

对于 pip>=10.x 使用:

from pip._internal.utils.misc import get_installed_distributions

为什么这样? 有时您会遇到应用程序名称冲突的情况。 从应用程序命名空间导入并不能让您全面了解系统上安装的内容。

结果,您将获得 pkg_resources.Distribution 对象的列表。 请参阅以下示例:

print installed_packages
[
    "Django 1.6.4 (/path-to-your-env/lib/python2.7/site-packages)",
    "six 1.6.1 (/path-to-your-env/lib/python2.7/site-packages)",
    "requests 2.5.0 (/path-to-your-env/lib/python2.7/site-packages)",
]

列出它:

flat_installed_packages = [package.project_name for package in installed_packages]

[
    "Django",
    "six",
    "requests",
]

检查 requests 是否已安装:

if 'requests' in flat_installed_packages:
    # Do something

Updated answer

A better way of doing this is:

import subprocess
import sys

reqs = subprocess.check_output([sys.executable, '-m', 'pip', 'freeze'])
installed_packages = [r.decode().split('==')[0] for r in reqs.split()]

The result:

print(installed_packages)

[
    "Django",
    "six",
    "requests",
]

Check if requests is installed:

if 'requests' in installed_packages:
    # Do something

Why this way? Sometimes you have app name collisions. Importing from the app namespace doesn't give you the full picture of what's installed on the system.

Note, that proposed solution works:

  • When using pip to install from PyPI or from any other alternative source (like pip install http://some.site/package-name.zip or any other archive type).
  • When installing manually using python setup.py install.
  • When installing from system repositories, like sudo apt install python-requests.

Cases when it might not work:

  • When installing in development mode, like python setup.py develop.
  • When installing in development mode, like pip install -e /path/to/package/source/.

Old answer

A better way of doing this is:

import pip
installed_packages = pip.get_installed_distributions()

For pip>=10.x use:

from pip._internal.utils.misc import get_installed_distributions

Why this way? Sometimes you have app name collisions. Importing from the app namespace doesn't give you the full picture of what's installed on the system.

As a result, you get a list of pkg_resources.Distribution objects. See the following as an example:

print installed_packages
[
    "Django 1.6.4 (/path-to-your-env/lib/python2.7/site-packages)",
    "six 1.6.1 (/path-to-your-env/lib/python2.7/site-packages)",
    "requests 2.5.0 (/path-to-your-env/lib/python2.7/site-packages)",
]

Make a list of it:

flat_installed_packages = [package.project_name for package in installed_packages]

[
    "Django",
    "six",
    "requests",
]

Check if requests is installed:

if 'requests' in flat_installed_packages:
    # Do something
酒绊 2024-08-01 09:37:51

如果您想从终端进行检查,可以运行

pip3 show package_name

,如果没有返回任何内容,则说明该软件包尚未安装。

如果您想自动执行此检查,以便在丢失时安装它,则可以在 bash 脚本中包含以下内容:

pip3 show package_name 1>/dev/null #pip for Python 2
if [ $? == 0 ]; then
   echo "Installed" #Replace with your actions
else
   echo "Not Installed" #Replace with your actions, 'pip3 install --upgrade package_name' ?
fi

If you want to have the check from the terminal, you can run

pip3 show package_name

and if nothing is returned, the package is not installed.

If perhaps you want to automate this check, so that for example you can install it if missing, you can have the following in your bash script:

pip3 show package_name 1>/dev/null #pip for Python 2
if [ $? == 0 ]; then
   echo "Installed" #Replace with your actions
else
   echo "Not Installed" #Replace with your actions, 'pip3 install --upgrade package_name' ?
fi
没有你我更好 2024-08-01 09:37:51

打开命令提示符类型

pip3 list

Open your command prompt type

pip3 list
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文