【问题标题】:Finding python site-package directory in debian container?在 debian 容器中查找 python 站点包目录?
【发布时间】:2021-09-23 16:34:33
【问题描述】:

我创建了一个 docker 容器:

FROM mcr.microsoft.com/vscode/devcontainers/base:0.202.2-debian-11

RUN sudo apt update && \
    sudo apt -y upgrade && \
    sudo apt -y install graphviz && \
    sudo apt -y install python3-venv python3-pip && \
    python3 -m pip install --upgrade pip && \
    pip install flake8 wheel

而且我发现从标准方式查找站点包目录的结果出乎意料。

正确的位置是/usr/local/lib/python3.9/dist-packages,并且包含安装在RUN 命令中的flake8 包(以及它作为依赖项的mccabe、pyflakes、pycodestyle)。运行例如容器中的pip install magicmethods 也会在这个目录下安装包。

但是,sysconfig 给出:

>>> import sysconfig
>>> sysconfig.get_paths()['purelib']
'/usr/lib/python3.9/site-packages'

这是一个不存在的目录。

distutils 给出:

>>> from distutils.sysconfig import get_python_lib
>>> get_python_lib()
'/usr/lib/python3/dist-packages'

确实存在(并包含 lsb_release.py、setuptools 和 wheel),但在此上下文中不是正确的目录。

我是否使用了错误的代码来查找站点包?

【问题讨论】:

  • __file__ 可能很有用——尤其是在不同文件夹中安装了软件包的情况下。例如,pyflakes.__file__
  • 我想我可以做到 import pip;print(pip.__file__.split("pip")[0] 但是当 Python 有应该直接告诉我的库时,这似乎非常糟糕......

标签: python docker debian


【解决方案1】:

我缺少的函数是 site.getsitepackages(),尽管它会返回一个包含可能不存在的目录的列表。

我的代码尝试查找已安装模块的包名称 - 即您列出

django-cms

在 requirements.txt 中,但要导入您需要的已安装模块:

import cms

所以工作代码是(只需要第二个for循环之前的部分来回答问题......):

import site

def find_package_names():
    res = {}

    site_package_dirs = [site.getusersitepackages()]
    site_package_dirs += site.getsitepackages()

    for site_packages in reversed(site_package_dirs):
        if not os.path.isdir(site_packages):
            continue

        # site_package_dirs now contains a list of existing directories

        for pth in os.listdir(site_packages):
            if not pth.endswith('.dist-info'):
                continue
            pkgname = pth.split('-', 1)[0].replace('_', '-')
            top_level_fname = os.path.join(site_packages, pth, 'top_level.txt')
            if not os.path.exists(top_level_fname):
                continue

            with open(top_level_fname) as fp:
                modnames = fp.read().split()

            for modname in modnames:
                modname = modname.replace('/', '.')
                res[modname] = pkgname

    return res

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2010-09-12
    • 1970-01-01
    • 2019-12-09
    • 1970-01-01
    • 2023-03-19
    • 1970-01-01
    相关资源
    最近更新 更多