问题描述
我想使用两个 Python 库(Google 的 Cloud Library,以及它们的 Cloud SDK),但它们的名称有冲突(它们都使用 google
在它们的基本导入名称中,并且不在内部使用相对导入).如何在单个应用中使用它们?
更改库的代码以使用正确的相对导入是不切实际的.另外,我知道我可以使用 virtualenv 从单独的 Python 应用程序访问这些库,但是如何从同一个 Python 应用程序中访问它们?
命名冲突详情
以下是有关导入的一些详细信息.当我从云库中导入一个模块时(我运行 import google.cloud.datastore
),该库中的另一个导入有一个例外:
图书馆正在尝试进行绝对导入,而不是相对导入.谷歌云库无法导入google.cloud.datastore.batch
的原因是SDK中已经定义了google
,存在命名冲突:
由于云库使用绝对导入,并且SDK中已经定义了名称google
,所以导入失败.
google
包注意将自己注册为 namespace 包.通过正确设置sys.path
,这里没有冲突.
您需要正确设置库环境.在项目的根目录中添加一个 appengine_config.py
文件:
来自 google.appengine.ext 导入供应商# 添加安装在lib"文件夹中的任何库.vendor.add('lib')
这会在 sys.path
的正确位置添加 lib
子目录.请参阅安装第三方-在 App Engine 上开发 Python 应用 How-To 中的派对库部分.
从这里开始导入 google.cloud
就可以了:
$ ls -1d lib *.py *.yaml应用程序.yamlappengine_config.py库主文件$ pip install -t lib google-cloud# 安装到lib子目录$ cat main.py导入谷歌从 google.cloud 导入数据存储从 google.appengine.api 导入内存缓存导入 os.path这里 = os.path.dirname(os.path.abspath(__file__))def app(*args, **kwargs):返回 '''谷歌:{}<br/>google.cloud.datastore:{}<br/>google.appengine.api.memcache: {}'''.format(os.path.relpath(google.__file__, 这里),os.path.relpath(datastore.__file__, here),os.path.relpath(memcache.__file__, 这里))
并在浏览器中为我提供服务:
google:../google-cloud-sdk/platform/google_appengine/google/__init__.pygoogle.cloud.datastore: lib/google/cloud/datastore/__init__.pycgoogle.appengine.api.memcache:../google-cloud-sdk/platform/google_appengine/google/appengine/api/memcache/__init__.pyc
I want to use two Python libraries (Google's Cloud Library, and their Cloud SDK) in a single application, but they have conflicting names (they both use google
in their base import names and do not use relative imports internally). How can I use them in a single app?
Changing the library's code to use proper relative imports is not practical. Also, I know I can use virtualenv to access these libraries from separate python applications, but how do I access them from within the same python app?
Details of the Naming Conflict
Here are some of the details on the import. When I import a module from the Cloud Library (I run import google.cloud.datastore
), there is an exception about another import within that library:
>>> import libs.google.cloud.datastore
Traceback (most recent call last):
File "<console>", line 1, in <module>
File "C:[ProjectDIR]libsgoogleclouddatastore\__init__.py", line 52, in <module>
from google.cloud.datastore.batch import Batch
ImportError: No module named cloud.datastore.batch
The library is trying to do an absolute import, rather than a relative one. The reason that the Google Cloud Library cannot import google.cloud.datastore.batch
is because google
is already defined in the SDK, there is a naming conflict:
>>> print google.__path__
['C:\Program Files (x86)\Google\Cloud SDK\google-cloud-sdk\platform\google_appengine\google']
Because the Cloud Library uses absolute imports, and the name google
is already defined in the SDK, then the import fails.
The google
packages take care to register themselves as a namespace package. With a properly set up sys.path
there is no conflict here.
You need to set up your library environment correctly. Add a appengine_config.py
file in the root of your project with:
from google.appengine.ext import vendor
# Add any libraries installed in the "lib" folder.
vendor.add('lib')
This adds the lib
subdirectory in the right location of sys.path
. See the Installing a third-party library section in the Developing Python Apps on App Engine How-To.
From here on out imports of google.cloud
just work:
$ 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))
and in the browser I am served:
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
这篇关于使用两个名称冲突的 Python 库的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!