我如何找到我的站点包目录的位置?


当前回答

对于我正在从事的一个项目,我必须做一些稍微不同的事情:找到相对于基本安装前缀的相对site-packages目录。如果site-packages文件夹在/usr/lib/python2.7/site-packages中,我想要/lib/python2.7/site-packages部分。事实上,我遇到过站点包在/usr/lib64中的系统,接受的答案在这些系统上不起作用。

与作弊者的答案类似,我的解决方案深入Distutils的内部,以找到在setup.py中实际传递的路径。搞清楚这件事让我很痛苦,我不想让任何人再搞清楚这件事。

import sys
import os
from distutils.command.install import INSTALL_SCHEMES

if os.name == 'nt':
    scheme_key = 'nt'
else:
    scheme_key = 'unix_prefix'

print(INSTALL_SCHEMES[scheme_key]['purelib'].replace('$py_version_short', (str.split(sys.version))[0][0:3]).replace('$base', ''))

这应该打印类似/Lib/site-packages或/Lib/ python3.6/site-packages之类的东西。

其他回答

所有的答案(或者:重复同样的答案)都是不充分的。你要做的是:

from setuptools.command.easy_install import easy_install
class easy_install_default(easy_install):
  """ class easy_install had problems with the fist parameter not being
      an instance of Distribution, even though it was. This is due to
      some import-related mess.
      """

  def __init__(self):
    from distutils.dist import Distribution
    dist = Distribution()
    self.distribution = dist
    self.initialize_options()
    self._dry_run = None
    self.verbose = dist.verbose
    self.force = None
    self.help = 0
    self.finalized = 0

e = easy_install_default()
import distutils.errors
try:
  e.finalize_options()
except distutils.errors.DistutilsError:
  pass

print e.install_dir

最后一行显示了安装目录。适用于Ubuntu,而上面的不能。不要问我关于windows或其他目录的问题,但由于它是easy_install默认使用的完全相同的目录,所以它可能在easy_install工作的任何地方都是正确的(所以,任何地方,甚至mac)。玩得开心。注意:原始代码中有很多脏话。

正如其他人所注意到的,distutils。Sysconfig有相关的设置:

import distutils.sysconfig
print distutils.sysconfig.get_python_lib()

...尽管默认的site.py做了一些更粗糙的事情,如下所述:

import sys, os
print os.sep.join([sys.prefix, 'lib', 'python' + sys.version[:3], 'site-packages'])

(它还添加了${sys. exe。Prefix}/lib/site-python,为sys. python添加两个路径。Exec_prefix也是,如果常量不同的话)。

也就是说,背景是什么?你不应该直接破坏你的站点包;Setuptools /distutils将用于安装,并且您的程序可能运行在一个virtualenv中,其中您的pythonpath完全是用户本地的,因此它也不应该假设直接使用系统站点包。

现代的stdlib方法是使用sysconfig模块,在2.7和3.2+版本中可用。与目前公认的答案不同,无论您是否激活了虚拟环境,此方法都仍然有效。

注意:不要将sysconfig (source)与distutils混淆。Sysconfig子模块(源)在这里的其他几个答案中提到。后者是一个完全不同的模块,它缺少下面讨论的get_paths函数。此外,distutils在3.10中已弃用,很快就不可用了。

Python目前使用八个路径(docs):

stdlib:包含非特定于平台的标准Python库文件的目录。 platstdlib:包含特定于平台的标准Python库文件的目录。 Platlib:特定于站点、特定于平台的文件的目录。 Purelib:特定于站点的、非平台特定的文件的目录。 包含:用于非平台特定头文件的目录。 Platinclude:平台特定头文件的目录。 Scripts:脚本文件目录。 Data:数据文件目录。

在大多数情况下,发现这个问题的用户可能对“purelib”路径感兴趣(在某些情况下,您可能对“platlib”也感兴趣)。purelib路径是pip等工具安装普通Python包的地方。

在系统层面,你会看到如下内容:

# Linux
$ python3 -c "import sysconfig; print(sysconfig.get_path('purelib'))"
/usr/local/lib/python3.8/site-packages

# macOS (brew installed python3.8)
$ python3 -c "import sysconfig; print(sysconfig.get_path('purelib'))"
/usr/local/Cellar/python@3.8/3.8.3/Frameworks/Python.framework/Versions/3.8/lib/python3.8/site-packages

# Windows
C:\> py -c "import sysconfig; print(sysconfig.get_path('purelib'))"
C:\Users\wim\AppData\Local\Programs\Python\Python38\Lib\site-packages

用venv,你会得到这样的东西

# Linux
/tmp/.venv/lib/python3.8/site-packages

# macOS
/private/tmp/.venv/lib/python3.8/site-packages

# Windows
C:\Users\wim\AppData\Local\Temp\.venv\Lib\site-packages

函数sysconfig.get_paths()返回所有相关安装路径的字典,以Linux为例:

>>> import sysconfig
>>> sysconfig.get_paths()
{'stdlib': '/usr/local/lib/python3.8',
 'platstdlib': '/usr/local/lib/python3.8',
 'purelib': '/usr/local/lib/python3.8/site-packages',
 'platlib': '/usr/local/lib/python3.8/site-packages',
 'include': '/usr/local/include/python3.8',
 'platinclude': '/usr/local/include/python3.8',
 'scripts': '/usr/local/bin',
 'data': '/usr/local'}

shell脚本也可用来显示这些细节,您可以通过将sysconfig作为模块执行来调用:

python -m sysconfig

附录:Debian / Ubuntu怎么样?

正如一些评论者指出的那样,Debian系统(以及Ubuntu,作为一个衍生版本)的sysconfig结果并不准确。当用户pip安装一个包时,它将进入dist-packages而不是site-packages,根据Debian对Python打包的策略。

造成这种差异的根本原因是Debian修补了distutils的安装布局,以正确地反映它们对站点的更改,但他们未能修补sysconfig模块。

例如,在Ubuntu 20.04.4 LTS (Focal Fossa)上:

root@cb5e85f17c7f:/# python3 -m sysconfig | grep packages
    platlib = "/usr/lib/python3.8/site-packages"
    purelib = "/usr/lib/python3.8/site-packages"

root@cb5e85f17c7f:/# python3 -m site | grep packages
    '/usr/local/lib/python3.8/dist-packages',
    '/usr/lib/python3/dist-packages',
USER_SITE: '/root/.local/lib/python3.8/site-packages' (doesn't exist)

看起来Debian/Ubuntu发布的Python补丁安装有点被黑了,当distutils完全不可用时,他们需要为3.12+想出一个新计划。可能,他们将不得不开始修补sysconfig,因为这是pip将用于安装位置的。

您应该尝试这个命令来确定pip的安装位置

Python 2

pip show six | grep "Location:" | cut -d " " -f2

Python 3

pip3 show six | grep "Location:" | cut -d " " -f2

假设你已经安装了“django”包。导入它并输入dir(django)。它将向您展示该模块的所有函数和属性。输入python解释器-

>>> import django
>>> dir(django)
['VERSION', '__builtins__', '__doc__', '__file__', '__name__', '__package__', '__path__', 'get_version']
>>> print django.__path__
['/Library/Python/2.6/site-packages/django']

如果您已经安装了mercurial,您也可以做同样的事情。

这是给雪豹的。但我认为它在一般情况下也适用。