【问题标题】:Using Two Python Libraries with Conflicting Names使用两个名称冲突的 Python 库
【发布时间】:2017-05-14 22:27:33
【问题描述】:

我想在一个应用程序中使用两个 Python 库(Google 的 Cloud Library 和它们的 Cloud SDK),但是它们的名称有冲突(它们都在基本导入名称中使用 google,并且不使用相对导入内部)。如何在单个应用中使用它们?

更改库的代码以使用正确的相对导入是不切实际的。另外,我知道我可以使用 virtualenv 从单独的 python 应用程序访问这些库,但是如何从同一个 python 应用程序中访问它们?

命名冲突的细节

以下是有关导入的一些详细信息。当我从云库中导入一个模块(我运行import google.cloud.datastore)时,该库中的另一个导入出现异常:

>>> import libs.google.cloud.datastore
Traceback (most recent call last):
  File "<console>", line 1, in <module>
  File "C:\[ProjectDIR]\libs\google\cloud\datastore\__init__.py", line 52, in <module>
    from google.cloud.datastore.batch import Batch
ImportError: No module named cloud.datastore.batch

库正在尝试进行绝对导入,而不是相对导入。谷歌云库无法导入google.cloud.datastore.batch的原因是SDK中已经定义了google,存在命名冲突:

>>> print google.__path__
['C:\\Program Files (x86)\\Google\\Cloud SDK\\google-cloud-sdk\\platform\\google_appengine\\google']

由于云库使用绝对导入,并且SDK中已经定义了名称google,所以导入失败。

【问题讨论】:

  • 第二个链接去谷歌应用引擎SDK(在google.appengine包下提供代码),第一个是google.cloud。我不明白这两者的名字是如何冲突的。您遇到什么问题?您可以随时以不同的名称导入模块; from google.cloud import datastore as gc_datastore 将绑定名称 gc_datastore 在您当前的模块中;原来的名字是什么并不重要。
  • 嗨@MartijnPieters,问题与库的内部结构有关。第一个链接的库不使用相对导入,因此当您尝试导入它时,您会遇到与第二个链接的命名冲突。请参阅此处的第 57 行:github.com/GoogleCloudPlatform/google-cloud-python/blob/master/…
  • 那么另一个实际上是否包含google.cloud.datastore 包?你没有明确地与那里的任何东西联系起来。而且我怀疑 Google App Engine SDK 已经包含 Cloud SDK 作为安装的一部分,因此您不需要安装另一个。
  • @MartijnPieters,我添加了更多细节。问题是两个库都定义了google,而云库使用绝对导入。不,SDK 不包含云库。 Cloud Libraries 是访问使用 REST 接口的 Cloud 资源的更新方式。
  • 你为什么在这个路径中使用libsimport libs.google.cloud.datastore?为什么不是顶级安装呢?那是你的真正的问题。

标签: python google-app-engine virtualenv google-cloud-platform python-import


【解决方案1】:

google 包注意将自己注册为 namespace 包。正确设置 sys.path 后,这里没有冲突

您需要正确设置库环境。在项目的根目录中添加一个appengine_config.py 文件:

from google.appengine.ext import vendor

# Add any libraries installed in the "lib" folder.
vendor.add('lib')

这会将lib 子目录添加到sys.path 的正确位置。请参阅在 App Engine 上开发 Python 应用程序操作指南中的 Installing a third-party library section

从这里开始导入google.cloud 正常工作

$ ls -1d lib *.py *.yaml
app.yaml
appengine_config.py
lib
main.py
$ pip install -t lib google-cloud
# installing into the lib subdirectory
$ cat main.py
import google
from google.cloud import datastore
from google.appengine.api import memcache
import os.path

here = os.path.dirname(os.path.abspath(__file__))

def app(*args, **kwargs):
    return '''
google: {}<br />
google.cloud.datastore: {}<br />
google.appengine.api.memcache: {}'''.format(
        os.path.relpath(google.__file__, here),
        os.path.relpath(datastore.__file__, here),
        os.path.relpath(memcache.__file__, here))

在浏览器中为我服务:

google: ../google-cloud-sdk/platform/google_appengine/google/__init__.py
google.cloud.datastore: lib/google/cloud/datastore/__init__.pyc
google.appengine.api.memcache: ../google-cloud-sdk/platform/google_appengine/google/appengine/api/memcache/__init__.pyc

【讨论】:

  • 好的,这个看起来不错,我试试看。但是您也可以导入 SDK 库吗?在一个文件中,我可以使用import google.cloud as gcloudimport google.appengine as appengine 吗?
  • @speedplane:已更新以添加 SDK 示例。是的,你可以。
  • 这有点小题大做,但是pip install -t lib google-cloud 命令在 lib 文件夹中添加了一堆不必要的东西(例如,egg-info、dist-info 文件)。有什么干净的方法可以只安装将要使用的库吗?还是我应该在安装后删除不必要的东西?
  • @speedplane:我不会担心这些,并且尽可能让事情变得简单。不要让新开发人员的引导过程复杂化。
  • @speedplane: IIRC(自从我从事 GAE 项目以来已经一两年了)您可以将忽略添加到您的 yaml 文件中,这样就不会上传这些 egg-info 目录,使用 skip_files option .
猜你喜欢
  • 2011-08-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-04-30
  • 1970-01-01
  • 2014-10-03
  • 2012-08-23
相关资源
最近更新 更多