【问题标题】:weird python sys.path values奇怪的 python sys.path 值
【发布时间】:2013-07-25 05:40:02
【问题描述】:

注意sys.path最左边的值,除了空字符串...

从根目录python -c "import sys; print(sys.path)" 给我:

['', '/home/brian/code/indep/chimai', '/home/brian/code/indep/google_search/src', '/usr/lib/python33.zip', 
'/usr/lib/python3.3', '/usr/lib/python3.3/plat-linux', '/usr/lib/python3.3/lib-dynload', '/usr/lib/python3.3/site-packages']

从我的主目录

['', '/home/brian/home/brian/code/indep/chimai', '/home/brian/code/indep/google_search/src', 
'/usr/lib/python33.zip', '/usr/lib/python3.3', '/usr/lib/python3.3/plat-linux', '/usr/lib/python3.3/lib-dynload', 
'/usr/lib/python3.3/site-packages']

来自 /boot/grub

['', '/boot/grub/home/brian/code/indep/chimai', '/home/brian/code/indep/google_search/src', '/usr/lib/python33.zip', 
/usr/lib/python3.3', '/usr/lib/python3.3/plat-linux', '/usr/lib/python3.3/lib-dynload', '/usr/lib/python3.3/site-packages']

无论我从哪个目录进行测试,这种行为都会继续。也就是说,您看到的 sys.path 的第二个和第三个值应该从我的 PYTHONPATH 变量中加载,但第一个值总是将我的当前目录附加到它的前面。

另外,python -Sc "import sys; print(sys.path) 不这样做,出于某种原因。使用该命令,我总是得到:

['', 'home/brian/code/indep/chimai', '/home/brian/code/indep/google_search/src', '/usr/lib/python33.zip', 
'/usr/lib/python3.3/', '/usr/lib/python3.3/plat-linux', '/usr/lib/python3.3/lib-dynload']

这一切都非常令人惊讶。 site.py 对此负责吗?有人可以指出我正确的方向吗?我只是想导入自己的模块,目前由于某种原因无法导入。

【问题讨论】:

  • 您是否忘记了 PYTHONPATH 中的前导斜杠?
  • 感谢您指出这一点!
  • 天哪,解决了。再次感谢
  • 有关 sys.path 工作原理的更多信息,请参阅此答案stackoverflow.com/a/38403654/850326

标签: python python-import pythonpath sys.path


【解决方案1】:

来自 site.py 的文档字符串:

"""Append module search paths for third-party packages to sys.path.

****************************************************************
* This module is automatically imported during initialization. *
****************************************************************

In earlier versions of Python (up to 1.5a3), scripts or modules that
needed to use site-specific modules would place ``import site''
somewhere near the top of their code.  Because of the automatic
import, this is no longer necessary (but code that does it still
works).

This will append site-specific paths to the module search path.  On
Unix (including Mac OSX), it starts with sys.prefix and
sys.exec_prefix (if different) and appends
lib/python<version>/site-packages as well as lib/site-python.
On other platforms (such as Windows), it tries each of the
prefixes directly, as well as with lib/site-packages appended.  The
resulting directories, if they exist, are appended to sys.path, and
also inspected for path configuration files.

A path configuration file is a file whose name has the form
<package>.pth; its contents are additional directories (one per line)
to be added to sys.path.  Non-existing directories (or
non-directories) are never added to sys.path; no directory is added to
sys.path more than once.  Blank lines and lines beginning with
'#' are skipped. Lines starting with 'import' are executed.

For example, suppose sys.prefix and sys.exec_prefix are set to
/usr/local and there is a directory /usr/local/lib/python2.5/site-packages
with three subdirectories, foo, bar and spam, and two path
configuration files, foo.pth and bar.pth.  Assume foo.pth contains the
following:

  # foo package configuration
  foo
  bar
  bletch

and bar.pth contains:

  # bar package configuration
  bar

Then the following directories are added to sys.path, in this order:

  /usr/local/lib/python2.5/site-packages/bar
  /usr/local/lib/python2.5/site-packages/foo

Note that bletch is omitted because it doesn't exist; bar precedes foo
because bar.pth comes alphabetically before foo.pth; and spam is
omitted because it is not mentioned in either path configuration file.

After these path manipulations, an attempt is made to import a module
named sitecustomize, which can perform arbitrary additional
site-specific customizations.  If this import fails with an
ImportError exception, it is silently ignored.

"""

就导入您自己的模块而言,以下规则适用:

如果模块在您当前的工作目录中,则可以使用简单的import mymodule 导入,如果它在当前工作目录的子目录中,则可以将其导入为subdir.mymodule,如果您在当前工作目录的子目录该包包含一个名为__init__.py 的文件,该文件声明了一个名为__all__ = ['modulename', 'another', 'etc'] 的列表,然后您可以from subdir import modulename import subdir 和使用subdir.etc.fn()

如果您的模块需要在多个地方而不是所有地方使用,您可以将其放在一个公共位置,然后在需要时将该位置附加/插入到 sys.path 中。如果它是您几乎一直都需要的东西,那么您可以将它添加到 your 站点包中,方法是将其放在适当的位置并添加一个 .pth 文件。最后,如果您认为其他人会从您的软件包中受益,您可以使用 distutils 将其捆绑并添加到奶酪店之类的地方或以其他方式分发。

【讨论】:

  • 所以... sys.prefix 设置为 $HOME... 的值还是什么?我不明白你(或者那个文档字符串,真的)想告诉我什么,但我已经检查过了,sys.prefix 当前设置为'/usr',所以我认为它不涉及。
  • 我想我会尝试采纳您关于导入的建议,尤其是在将位置附加到 sys.path 时;这很聪明。
  • 我有一个模式,我在测试子包时经常使用这种模式,这些子包依赖于主代码可用的其他包,但它们位于主代码的子目录而不是包项的子目录中我想单独测试。我所做的只是在读取import sys; sys.path.insert(0, '..'); 的非系统导入之前有一些条件代码,这允许在模块作为主程序的一部分运行时可以工作的导入仍然适用于独立测试。
猜你喜欢
  • 2016-06-02
  • 2019-08-05
  • 1970-01-01
  • 2014-06-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多