简体   繁体   English

Python 使用内置模块而不是在 sys.path 中找到的自定义 package

[英]Python using built-in module instead of custom package found in sys.path

I am having an odd issue with Python for an application I support.对于我支持的应用程序,我对 Python 有一个奇怪的问题。 The application was working until recently, but now one of its services is failing to start with a Python import error.该应用程序直到最近才正常工作,但现在它的一项服务无法启动,并出现 Python 导入错误。 No changes have been made that I can attribute to this problem.没有进行任何我可以归因于此问题的更改。

The application provides its own site-packages directory that contains a backports package, with a configparser package inside.该应用程序提供了自己的站点包目录,其中包含一个反向端口 package,其中包含一个 configparser package。 I am not the dev for this, it is commercial software that was in a working config until recently, so I think this is more of a systems issue than a development one.我不是这方面的开发人员,它是直到最近才在工作配置中的商业软件,所以我认为这更多的是系统问题而不是开发问题。

The error is:错误是:

    Traceback (most recent call last):
      File "<app_dir>/tools/vault/bin/vault-unseal.py", line 12, in <module>
        import configparser
      File "<app_dir>/python-site/lib/python2.7/site-packages/configparser.py", line 11, in <module>
        from backports.configparser import (
    ImportError: No module named configparser

My sys.path is:我的 sys.path 是:

['',
 '/usr/lib/python2.7/site-packages/pip-19.3.1-py2.7.egg',
 '<app_dir>/python-site/lib/python2.7/site-packages',
 '<app_dir>/python-site/lib64/python2.7/site-packages',
 '/usr/lib64/python27.zip',
 '/usr/lib64/python2.7',
 '/usr/lib64/python2.7/plat-linux2',
 '/usr/lib64/python2.7/lib-tk',
 '/usr/lib64/python2.7/lib-old',
 '/usr/lib64/python2.7/lib-dynload',
 '/usr/lib64/python2.7/site-packages',
 '/usr/lib64/python2.7/site-packages/gtk-2.0',
 '/usr/lib/python2.7/site-packages']

Both these package directories exists with an __init__.py :这两个 package 目录都存在__init__.py

<app_dir>/python-site/lib/python2.7/site-packages/backports
<app_dir>/python-site/lib/python2.7/site-packages/backports/configparser

If I start up a python shell and run 'import backports' it will succeed, but instead of importing the correct custom version ( <app_dir>/python-site/lib/python2.7/site-packages/backports ) it will instead import a built-in.如果我启动 python shell 并运行“import backports”它会成功,但不是导入正确的自定义版本( <app_dir>/python-site/lib/python2.7/site-packages/backports )而是导入一个内置的。 That built-in lacks the configparser package.该内置缺少 configparser package。 Why is this happening?为什么会这样? The correct directory with the custom package is listed higher in the sys.path, so it should import that one instead, right?具有自定义 package 的正确目录列在 sys.path 的较高位置,所以它应该导入那个目录,对吧?

>>> import backports
>>> print(backports.__path__)
['/usr/lib/python2.7/site-packages/backports']
>>> backports
<module 'backports' (built-in)>

I was referring to this thread Python ImportError when module is in sys.path which has a similar issue. 当模块位于 sys.path 中时,我指的是这个线程 Python ImportError ,它有类似的问题。 I believe that none of the 3 listed solutions apply though.我相信列出的 3 个解决方案都不适用。 PYTHONPATH does contain the package directory; PYTHONPATH 确实包含 package 目录; the packages are structured correctly with __init__.py ;使用__init__.py正确构建包; and only one version of python is in use on the system (as far as I can tell; if there is a simple way to validate this I would do it).并且系统上只有一个版本的 python 正在使用(据我所知;如果有一种简单的方法可以验证这一点,我会这样做)。

I'm at a loss, any ideas would be very appreciated.我很茫然,任何想法都会非常感激。

So I just had basically the same problem, though it was my system python that got into a rather unfortunate state.所以我基本上遇到了同样的问题,虽然是我的系统 python 陷入了相当不幸的 state。 You need to figure out where it is finding backports/__init__.py and make sure you have configparser installed into that folder.您需要弄清楚它在哪里找到backports/__init__.py并确保您已将 configparser 安装到该文件夹中。 In my case, it appeared I had a backports folder in both /usr/lib/python2.7/site-packages and /usr/lib64/python2.7/site-packages .就我而言,似乎我在/usr/lib/python2.7/site-packages/usr/lib64/python2.7/site-packages都有一个 backports 文件夹。 The later had configparser in it, the former did not.后者有configparser ,前者没有。 The former is where it was actually loading the __init__.py from.前者是它实际加载__init__.py的地方。 I figured this out by doing我通过这样做解决了这个问题

from backports import functools_lru_cache

and then printing out the path where it found functools_lru_cache .然后打印出找到functools_lru_cache的路径。 If you don't have that module installed (or some other backported module), you're just going to have to try trial and error.如果您没有安装该模块(或其他一些向后移植的模块),您将不得不尝试反复试验。 You could try to put print statements into all the __init__.py files in all the backport folders on your machine and see which one triggers.您可以尝试将打印语句放入机器上所有 backport 文件夹中的所有__init__.py文件中,然后查看哪个触发。

Once I installed configparser into the backports folder in the location where it was being loaded from, I was able to load everything fine.一旦我将 configparser 安装到加载它的位置的 backports 文件夹中,我就可以正常加载所有内容。

> python
Python 2.7.18 (default, Apr 23 2020, 09:27:04) [GCC] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import backports
>>> print backports
<module 'backports' (built-in)>
>>> from backports import configparser
>>> print configparser
<module 'backports.configparser' from '/usr/lib/python2.7/site-packages/backports/configparser/__init__.pyc'>

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM