调试sys.path的修改

5

有些库似乎修改了我的 sys.path,虽然我不希望它被改变。

如何找到改变 sys.path 的 python 代码行?

相关问题


你可以先检查sys.path,然后导入模块并再次检查它。 - ForceBru
2个回答

9

首先被导入的是sitecustomizeusercustomize模块;你可以用自定义的列表实现来替换sys.path,记录所有正在进行的更改。

首先找到放置usercustomizesitecustomize模块的位置;site模块可以告诉你如何放置第一个模块:

python -m site --user-site

如果该目录尚不存在,请创建它,并在其中放置一个名为usercustomize.py的文件,其中包含以下内容:
import sys

class VerboseSysPath(list):
    def croak(self, action, args):
        frame = sys._getframe(2)
        print('sys.path.{}{} from {}:{}'.format(
            action, args, frame.f_code.co_filename, frame.f_lineno))

    def insert(self, *args):
        self.croak('insert', args)
        return super().insert(*args)
    
    def append(self, *args):
        self.croak('append', args)
        return super().append(*args)

    def extend(self, *args):
        self.croak('extend', args)
        return super().extend(*args)

    def pop(self, *args):
        self.croak('pop', args)
        return super().pop(*args)

    def remove(self, *args):
        self.croak('remove', args)
        return super().remove(*args)

    def __delitem__(self, *args):
        self.croak('__delitem__', args)
        return super().__delitem__(*args)

    def __setitem__(self, *args):
        self.croak('__setitem__', args)
        return super().__setitem__(*args)

sys.path = VerboseSysPath(sys.path)

现在,任何尝试更改sys.path列表的操作都会受到警告。

以下是演示内容,可以将其放置在site-packages/sitecustomize.py`python -m site --user-site`/usercustomize.py模块中:

$ cat test.py 
import sys

sys.path.append('')
$ bin/python test.py 
sys.path.append('',) from test.py:3

对于遇到类似问题的任何人:我无法通过将此代码添加到sitecustomize.py来跟踪sys.path中未解释的条目,因此我最终临时将其破解到site.py本身中,并成功解决了问题(残留的.pth文件来自有缺陷的安装)。 site.py位于lib文件夹中。值得注意的是;如果您使用虚拟环境,则核心库不会随附,只有lib/site-packages。您可以通过查看sys.path中前几个条目来找到基本安装位置。 - MarcinKonowalczyk
1
@MarcinKonowalczyk:啊,是的,.pth文件在导入*customize模块之前被处理。请注意,用户级别的site-packages目录中的.pth文件会在site目录中的文件之前加载,并且在这样的文件中以import开头的任何行都会被执行,因此您可以使用.pth文件来代替usercustomize模块来加载相同的sys.path工具,并且不需要修改site.py - Martijn Pieters

2
使用 python -S 启动 Python 会导致 Python 不加载 site.py,因此它的默认值会保留自 Python 第一次启动时的值。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接