必要时安装库

install a library if necessary

我想向一位同学发送一个我引以为豪的短代码,但意识到他无法 运行,因为他没有理由安装该库。 安装当然非常容易 - 但我意识到这可能经常发生,主要是初学者 - 想为其构建一个简单的功能:

def smart_import(package_name):
    try:
        import package_name
    except ImportError:
        import pip
        pip.main(['install', package_name])

问题是我真的不知道如何将包的名称作为可以通过导入调用的值传递 想过将字符串转换回来,但这似乎比我想的更复杂

出于多种原因,这是一个坏主意,主要原因是人们通常不希望 Python 函数调用自动尝试在他们的计算机上安装软件。

以下是此方法存在的其他一些问题

  • 导入名称并不总是对应于分发名称。例如 dateutil 模块由 python-dateutil 发行版提供。
  • 如果您尝试从另一个模块使用 smart_import,它会将名称导入到错误的命名空间中。
  • 一些发行版导出多个 top-level 导入,例如setuptools 提供 setuptoolseasy_installpkg_resources
  • 在某些情况下,pip本身可能没有安装。
  • 脚本可能没有安装包的权限。
  • 用户可能想使用 --user 明确地将发行版安装到他们的 homedir 中,而您的脚本本身并不知道。
  • pip 的调用可能需要根据您是否在 virtualenv 中进行更改。
  • 安装可能会尝试引入依赖项,这会导致与用户安装的其他发行版发生冲突。
  • IDE 可能看不到动态导入的模块存在,并且可能会在随后使用无法解析的名称时使用波浪线下划线。

改为做什么:

将您的代码打包到它自己的发行版中。编写一个 setup.py,它在 setup 调用中使用 install_requires 参数提及依赖项。请你的同学 pip install mypackage,依赖项将在安装时而不是运行时收集。您可以将您的发行版直接发送给他们(作为 mypackage-0.1.tar.gz 文件或 wheel). Or you can upload it to an index such as the test pypi.

Python Packaging User Guide 是描述如何创建和上传您自己的分发的 beginner-friendly 资源。