与 sys.path 顺序无关的与 SDK 包导入同名的 python 站点包

Posted

技术标签:

【中文标题】与 sys.path 顺序无关的与 SDK 包导入同名的 python 站点包【英文标题】:python site-package with same name as SDK package importing regardless of sys.path order 【发布时间】:2021-03-14 14:36:44 【问题描述】:

我正在尝试将 Google Cloud Shell 用作现有 App Engine 标准 Python 2.7 应用程序的远程开发环境。已经安装了 SDK,所有的通信路径都已经建立(无需担心云身份验证/应用程序默认凭据/等),并且可以使用完整的一次性 VM(无需使用虚拟环境或任何其他 python 疯狂来使事情正常运行在共享环境中),这似乎是兼职开发/维护的理想设置。

...唉,我无法导入任何 appengine/google 软件包。

这似乎是 Google Cloud Shell 内部的一个问题。所以这里是解释清楚的步骤:

打开一个全新的空 Google Shell: https://shell.cloud.google.com/

键入此以查看应用引擎 SDK 的安装路径:

someuser@cloudshell:~$ echo $(gcloud info --format="value(installation.sdk_root)")/platform/google_appengine
/usr/lib/google-cloud-sdk/platform/google_appengine

请注意,SDK 有一个 google_appengine/google 文件夹...包含一个 appengine 包:

someuser@cloudshell:~$ ls -la /usr/lib/google-cloud-sdk/platform/google_appengine/google
total 32
drwxr-xr-x  7 root root 4096 Nov 18 02:53 .
drwxr-xr-x  1 root root 4096 Nov 18 02:53 ..
drwxr-xr-x 12 root root 4096 Nov 18 02:53 appengine
-rw-r--r--  1 root root  601 Jan  1  1980 __init__.py
drwxr-xr-x  5 root root 4096 Nov 18 02:53 net
drwxr-xr-x  3 root root 4096 Nov 18 02:53 protobuf
drwxr-xr-x  2 root root 4096 Nov 18 02:54 __pycache__
drwxr-xr-x  3 root root 4096 Nov 18 02:53 pyglib

找到 python 站点包位置:

someuser@cloudshell:~$ python -c 'import site; print site.getsitepackages()'
['/usr/local/lib/python2.7/dist-packages', '/usr/lib/python2.7/dist-packages']

注意:其中一个目录也有一个 google 文件夹,其中包含 不同 包:

someuser@cloudshell:~$ ls -la /usr/local/lib/python2.7/dist-packages/google
total 60
drwxr-sr-x 15 root staff 4096 Nov 18 03:12 .
drwxrwsr-x  1 root staff 4096 Nov 18 03:40 ..
drwxr-sr-x  2 root staff 4096 Nov 18 03:11 api
drwxr-sr-x  5 root staff 4096 Nov 18 03:11 api_core
drwxr-sr-x  3 root staff 4096 Nov 18 03:11 _async_resumable_media
drwxr-sr-x  5 root staff 4096 Nov 18 03:11 auth
drwxr-sr-x 29 root staff 4096 Nov 18 03:12 cloud
drwxr-sr-x  3 root staff 4096 Nov 18 03:12 iam
drwxr-sr-x  3 root staff 4096 Nov 18 03:11 logging
drwxr-sr-x  2 root staff 4096 Nov 18 03:11 longrunning
drwxr-sr-x  2 root staff 4096 Nov 18 03:11 oauth2
drwxr-sr-x  6 root staff 4096 Nov 18 03:11 protobuf
drwxr-sr-x  3 root staff 4096 Nov 18 03:11 resumable_media
drwxr-sr-x  3 root staff 4096 Nov 18 03:11 rpc
drwxr-sr-x  2 root staff 4096 Nov 18 03:11 type

好的..让我们开始python:

someuser@cloudshell:~$ python

Python 2.7.16 (default, Oct 10 2019, 22:02:15)
[GCC 8.3.0] on linux2

# let's inspect the sys.path

>>> import sys

>>> sys.path
['', '/usr/lib/python2.7', '/usr/lib/python2.7/plat-x86_64-linux-gnu', '/usr/lib/python2.7/lib-tk', '/usr/lib/python2.7/lib-old', '/usr/lib/python2.7/lib-dynload', '/usr/local/lib/python2.7/dist-packages', '/usr/lib/python2.7/dist-packages']

# ^^ our SDK path isn't in there.  let's add it to the front of the list in the manner we're supposed to

>>> sys.path.insert(1, '/usr/lib/google-cloud-sdk/platform/google_appengine')

# lets look again

>>> sys.path
['', '/usr/lib/google-cloud-sdk/platform/google_appengine', '/usr/lib/python2.7', '/usr/lib/python2.7/plat-x86_64-linux-gnu', '/usr/lib/python2.7/lib-tk', '/usr/lib/python2.7/lib-old', '/usr/lib/python2.7/lib-dynload', '/usr/local/lib/python2.7/dist-pa
ckages', '/usr/lib/python2.7/dist-packages']

# ok, that should work... RIGHT?


>>> from google.appengine.api import urlfetch
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ImportError: No module named appengine.api

# NOPE... where's "appengine"???

>>> import google

# ummm....

>>> google.__path__
['/usr/local/lib/python2.7/dist-packages/google']

# ummmmmmmmmm.....

所以有几个问题,我不明白它们之间的关系或如何解决:

cloud shell 的 google 包与 SDK 中的 google 包冲突 为什么 sys.path 仍然不被尊重?

这与包命名空间或其他东西有关...我不够聪明,无法弄清楚...请帮助!

【问题讨论】:

你能解释一下你为什么要这样做吗?为什么需要在 Cloud Shell 中from google.appengine.api import urlfetch @DustinIngram 好点...我已经在顶部更新了更多“为什么”的问题! 【参考方案1】:

google.appengine 模块已融入第一代 Python (2.7) 运行时。无法通过pip、第二代 (3.x) 运行时或 Cloud Shell 安装。

使用它的唯一方法是编写和部署第一代 App Engine 应用。

【讨论】:

是的,我们已经有了第一代 App Engine 应用程序,这是我正在努力开发的。我可以将我们的应用程序克隆到云 shell 中,但无法运行测试或我们构建的任何实用程序。第一代 SDK 似乎已经在 Cloud Shell 中可用......但是站点包中另一个 google 文件夹的存在令人头疼。我想知道如何通过忽略这个其他谷歌文件夹来使用我们现有的第一代云外壳中的应用程序......但我无法弄清楚

以上是关于与 sys.path 顺序无关的与 SDK 包导入同名的 python 站点包的主要内容,如果未能解决你的问题,请参考以下文章

Python高级语法-import导入-sys.path(4.4.1)

导入模块的搜索路径以及sys.path

导入模块的顺序导入模块的实质sys模块

016-1 模块-模块的加载顺序导入执行流程

第十七节:模块的导入总结

写给新手的Python导入机制详解