Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/283.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/google-app-engine/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
将第三方软件包目录添加到Python路径开头的最干净的方法是什么?_Python_Google App Engine_Python 2.7_Python Import_Pythonpath - Fatal编程技术网

将第三方软件包目录添加到Python路径开头的最干净的方法是什么?

将第三方软件包目录添加到Python路径开头的最干净的方法是什么?,python,google-app-engine,python-2.7,python-import,pythonpath,Python,Google App Engine,Python 2.7,Python Import,Pythonpath,我的上下文是appengine_config.py,但这实际上是一个一般的Python问题 假设我们克隆了一个应用程序的repo,其中有一个空目录lib,并且我们使用命令pip install-r requirements.txt--target lib用包填充lib,那么: dirname ='lib' dirpath = os.path.join(os.path.dirname(__file__), dirname) 出于导入目的,我们可以通过以下方式将这样一个文件系统路径添加到Pytho

我的上下文是appengine_config.py,但这实际上是一个一般的Python问题


假设我们克隆了一个应用程序的repo,其中有一个空目录
lib
,并且我们使用命令
pip install-r requirements.txt--target lib
用包填充
lib
,那么:

dirname ='lib'
dirpath = os.path.join(os.path.dirname(__file__), dirname)
出于导入目的,我们可以通过以下方式将这样一个文件系统路径添加到Python路径的开头(我们使用索引1,因为第一个位置应该保持为“.”,即当前目录):

但是,如果该目录中的任何包都是命名空间包,那么这将不起作用

为了支持命名空间包,我们可以改为使用:

site.addsitedir(dirpath)
但这会将新目录附加到路径的末尾,我们不希望在需要用更新版本覆盖平台提供的包(如WebOb)时使用新目录

到目前为止,我的解决方案是这段代码,我很想简化它:

sys.path, remainder = sys.path[:1], sys.path[1:]
site.addsitedir(dirpath)
sys.path.extend(remainder)

是否有更干净或更具Python风格的方法来完成此任务?

对于这个答案,我假设您知道如何使用
setuptools
setup.py

假设您希望使用标准的
setuptools
工作流进行开发,我建议您使用
appengine\u config.py
中截取的代码:

import os
import sys

if os.environ.get('CURRENT_VERSION_ID') == 'testbed-version':
    # If we are unittesting, fake the non-existence of appengine_config.
    # The error message of the import error is handled by gae and must
    # exactly match the proper string.
    raise ImportError('No module named appengine_config')


# Imports are done relative because Google app engine prohibits
# absolute imports.
lib_dir = os.path.join(os.path.dirname(os.path.realpath(__file__)), 'libs')
# Add every library to sys.path.
if os.path.isdir(lib_dir):
    for lib in os.listdir(lib_dir):
        if lib.endswith('.egg'):
            lib = os.path.join(lib_dir, lib)
            # Insert to override default libraries such as webob 1.1.1.
            sys.path.insert(0, lib)
这段代码位于
setup.cfg

[develop]
install-dir = libs
always-copy = true
如果键入
python setup.py develope
,库将作为鸡蛋下载到
libs
目录中
appengine\u config
将它们插入到您的路径中


我们在工作中使用它来包括
webob==1.3.1
和内部包,这些包都是使用我们公司名称空间命名的。

您可能想看看堆栈溢出线程中的答案,“,”但是对于您在名称空间包方面的特殊困境,您遇到了。请随意添加到该讨论中,并链接到此用例

我想谈谈你说的另一件我认为是误导的事情:

我的上下文是appengine_config.py,但这实际上是一个通用Python 问题

这个问题实际上源于Google App Engine的局限性和无法安装第三方软件包,因此,需要寻求解决办法。而不是手动调整
sys.path
并使用
site.addsitedir
。在一般的Python开发中,如果您的代码使用了这些,那么您就做错了

以下是我概述的:

  • 创建一个虚拟环境
  • setup.py
    和/或需求文件中标出您的依赖项(请参阅)
  • 使用pip将依赖项安装到virtualenv中
  • 使用pip和
    -e/--editable
    标志将项目本身安装到virtualenv中
  • 不幸的是,Google App Engine与virtualenv和pip不兼容。GAE选择在尝试沙箱环境中阻止此工具集。因此,必须使用hacks来绕过GAE的限制,以使用其他或更新的第三方库


    如果您不喜欢这个限制,并且希望使用标准Python工具来管理第三方软件包依赖项,那么您可以期待您的业务。

    谢谢您的回答。我想到的工作流程基本上是:
    pip install-r requirements.txt-t'lib'
    appengine\u config.py的想法是一样的,除了您案例中的依赖项在
    requirements.txt
    中指定,而不是在
    setup.py
    pip install-r requirements.txt中指定之外,t'lib'
    没有用鸡蛋填充lib目录。看起来pip有一个-e开关:但它只适用于VCS或本地文件引用,因此,
    pip安装-e-r requirements.txt-t lib/
    失败。我在Q中添加了缺失的上下文。有意义吗?我以前也遇到过这种问题,比如在构建插件时,它需要的依赖项与插入的系统略有不同。您不能使用
    site.addsitedir()
    ,因为它是只附加的行为,也不能使用
    sys.path.insert()
    ,因为命名空间包。诚然,在非托管web平台环境中,还有一些其他途径需要探索(例如强制插入式应用程序升级,或者让插件在其自身进程中运行),但是这个问题并不是GAE独有的。我跟进了你的建议,从问题追踪者那里链接到这个Q:谢谢你花时间添加到这个问题上。不客气。因此,考虑到
    site.addsitedir()
    没有左附加选项,我的问题中有任何关于实际改进或简化代码的建议吗?顺便说一句,我在线程上编辑了最接近的答案,以更接近我当前的解决方案。我当前的版本将大部分代码移动到
    insertsitedir()中
    函数在
    vendor.py
    模块中,但在其他方面没有真正改变。仍然在寻找改进或简化(如果可能的话)。经过更多的迭代,John Wayne Parrott已经打包了生成的代码:
    [develop]
    install-dir = libs
    always-copy = true