【问题标题】:Using python subprocess to launch a python script in a different anaconda environment使用python子进程在不同的anaconda环境中启动python脚本
【发布时间】:2021-12-30 00:11:29
【问题描述】:

我需要启动一个 python 脚本,该脚本需要与启动它的 python 脚本不同的环境。我目前正在尝试使用 subprocess 模块创建一个新的进程和 windows bat 文件,以设置第二个 Anaconda 环境,然后启动该脚本。

在不同环境下将此过程设为两步过程的基本原理是,该工具需要在 ESRI 的 ArcPro GUI 中作为脚本工具运行。该软件附带 Anaconda 安装,允许用户制作可以从 GUI 运行的自己的环境和脚本,但是它强制这些环境安装自己的 ArcPy 包,我找不到允许我的脚本的包组合与 ArcPy 一起存在。因此,我打算使用默认的 ArcPro Anaconda 环境来运行将参数记录到文本文件的脚本,然后启动子进程,该子进程将使用 bat 文件设置单独的 Anaconda 环境并启动第二个脚本。

我在最后一步的尝试目前看起来像这样:

subprocess.Popen("C:\\Windows\\System32\\cmd.exe C:\\Users\RDCHLNRO\\AppData\\Local\\Continuum\\anaconda3\\Scripts\\__TESTFORARC.bat")

这个用于启动 Anaconda 的 bat 文件是从 Anaconda 自己的 activate.bat 复制而来的:

@set "_args1=%1"
@set _args1_first=%_args1:~0,1%
@set _args1_last=%_args1:~-1%
@set _args1_first=%_args1_first:"=+%
@set _args1_last=%_args1_last:"=+%
@set _args1=
@if "%_args1_first%"=="+" if NOT "%_args1_last%"=="+" (
    @CALL "%~dp0..\condabin\conda.bat" activate
    @CALL conda activate myenv
    @CALL C:\Users\RDCHLNRO\AppData\Local\Continuum\anaconda3\envs\myenv\python.exe C:\Users\RDCHLNRO\Desktop\waves2021\cc_ARC.py
    
    @GOTO :End
)
@REM This may work if there are spaces in anything in %*
@CALL "%~dp0..\condabin\conda.bat" activate %*
@CALL conda activate myenv
@CALL C:\Users\RDCHLNRO\AppData\Local\Continuum\anaconda3\envs\myenv\python.exe C:\Users\RDCHLNRO\Desktop\waves2021\cc_ARC.py

:End
@set _args1_first=
@set _args1_last=

这会导致 Windows 命令提示符启动,结果如下:

Traceback (most recent call last):
  File "C:\Users\RDCHLNRO\AppData\Local\Continuum\anaconda3\Scripts\conda-script.py", line 11, in <module>
    from conda.cli import main
ModuleNotFoundError: No module named 'conda'

CommandNotFoundError: 'activate'

    Traceback (most recent call last):
      File "C:\Users\RDCHLNRO\Desktop\waves2021\cc_LZMST_ARC.py", line 5, in <module>
        import numpy as np
      File "C:\Users\RDCHLNRO\AppData\Local\Programs\ArcGIS\Pro\bin\Python\envs\arcgispro-py3\Lib\site-packages\numpy\__init__.py", line 140, in <module>
        from . import core
      File "C:\Users\RDCHLNRO\AppData\Local\Programs\ArcGIS\Pro\bin\Python\envs\arcgispro-py3\Lib\site-packages\numpy\core\__init__.py", line 101, in <module>
        from . import _internal
      File "C:\Users\RDCHLNRO\AppData\Local\Programs\ArcGIS\Pro\bin\Python\envs\arcgispro-py3\Lib\site-packages\numpy\core\_internal.py", line 18, in <module>
        IS_PYPY = platform.python_implementation() == 'PyPy'
      File "C:\Users\RDCHLNRO\AppData\Local\Programs\ArcGIS\Pro\bin\Python\envs\arcgispro-py3\Lib\platform.py", line 1262, in python_implementation
        return _sys_version()[0]
      File "C:\Users\RDCHLNRO\AppData\Local\Programs\ArcGIS\Pro\bin\Python\envs\arcgispro-py3\Lib\platform.py", line 1223, in _sys_version
        repr(sys_version))
    ValueError: failed to parse CPython sys.version: '3.7.10 (default, Feb 26 2021, 13:06:18) [MSC v.1916 64 bit (AMD64)]'

但是,如果我通过 windows 开始菜单启动 windows 命令提示符并将其指向我的 bat 文件,Anaconda 环境将启动并启动脚本。

我无法找到通过 ArcPro GUI 打开子进程的终端(错误后窗口仍然存在)和通过开始菜单打开的终端之间的任何区别,除了它们能够打开这个 bat 文件。两者都追溯到同一个 system32 文件夹。

我确信有更优雅的方式来完成整个过程,但在这一点上,我只想弄清楚为什么这些终端窗口,显然来自同一个可执行文件,具有如此不同的行为,以及我能做些什么来从 ArcPro 中的子进程启动的行为中获取所需的行为。

编辑

我想我发现了一些重要的新信息,我在 ArcPro 启动的命令提示符和通过开始菜单启动的命令提示符中都运行了 python -m site。

这是我的环境和脚本工作的开始菜单命令提示符的结果:

    sys.path = [
        'C:\\Users\\RDCHLNRO',
        'C:\\Users\\RDCHLNRO\\AppData\\Local\\Programs\\ArcGIS\\Pro\\bin\\Python\\envs\\myenv\\python37.zip',
        'C:\\Users\\RDCHLNRO\\AppData\\Local\\Programs\\ArcGIS\\Pro\\bin\\Python\\envs\\myenv\\DLLs',
        'C:\\Users\\RDCHLNRO\\AppData\\Local\\Programs\\ArcGIS\\Pro\\bin\\Python\\envs\\myenv\\lib',
        'C:\\Users\\RDCHLNRO\\AppData\\Local\\Programs\\ArcGIS\\Pro\\bin\\Python\\envs\\myenv',
        'C:\\Users\\RDCHLNRO\\AppData\\Local\\Programs\\ArcGIS\\Pro\\bin\\Python\\envs\\myenv\\lib\\site-packages',
    ]
    USER_BASE: 'C:\\Users\\RDCHLNRO\\AppData\\Roaming\\Python' (doesn't exist)
    USER_SITE: 'C:\\Users\\RDCHLNRO\\AppData\\Roaming\\Python\\Python37\\site-packages' (doesn't exist)
    ENABLE_USER_SITE: True

这是 ArcPro 启动的命令提示符的结果:

sys.path = [
    'C:\\Users\\RDCHLNRO\\AppData\\Local\\Programs\\ArcGIS\\Pro\\bin\\Python\\envs\\myenv',
    'C:\\Users\\RDCHLNRO\\AppData\\Local\\Programs\\ArcGIS\\Pro\\Resources\\ArcPy',
    'C:\\Users\\RDCHLNRO\\AppData\\Local\\Programs\\ArcGIS\\Pro\\bin\\Python\\envs\\arcgispro-py3\\DLLs',
    'C:\\Users\\RDCHLNRO\\AppData\\Local\\Programs\\ArcGIS\\Pro\\bin\\Python\\envs\\arcgispro-py3\\Lib',
    'C:\\Users\\RDCHLNRO\\AppData\\Local\\Programs\\ArcGIS\\Pro\\bin\\Python\\envs\\arcgispro-py3\\Lib\\site-packages',
    'c:\\users\\rdchlnro\\appdata\\local\\programs\\arcgis\\pro\\bin',
    'c:\\users\\rdchlnro\\appdata\\local\\programs\\arcgis\\pro\\Resources\\ArcToolbox\\Scripts',
    'C:\\Users\\RDCHLNRO\\AppData\\Local\\Programs\\ArcGIS\\Pro\\bin\\Python\\envs\\myenv\\python37.zip',
    'C:\\Users\\RDCHLNRO\\AppData\\Local\\Programs\\ArcGIS\\Pro\\bin\\Python\\envs\\arcgispro-py3',
    'C:\\Users\\RDCHLNRO\\AppData\\Local\\Programs\\ArcGIS\\Pro\\bin\\Python\\envs\\arcgispro-py3\\lib\\site-packages\\future-0.18.2-py3.7.egg',
    'C:\\Users\\RDCHLNRO\\AppData\\Local\\Programs\\ArcGIS\\Pro\\bin\\Python\\envs\\arcgispro-py3\\lib\\site-packages\\pytz-2020.1-py3.7.egg',
    'C:\\Users\\RDCHLNRO\\AppData\\Local\\Programs\\ArcGIS\\Pro\\bin\\Python\\envs\\arcgispro-py3\\lib\\site-packages\\pywin32_ctypes-0.2.0-py3.7.egg',
    'C:\\Users\\RDCHLNRO\\AppData\\Local\\Programs\\ArcGIS\\Pro\\bin\\Python\\envs\\arcgispro-py3\\lib\\site-packages\\pywin32security',
    'C:\\Users\\RDCHLNRO\\AppData\\Local\\Programs\\ArcGIS\\Pro\\bin\\Python\\envs\\arcgispro-py3\\lib\\site-packages\\sympy-1.5.1-py3.7.egg',
]
USER_BASE: 'C:\\Users\\RDCHLNRO\\AppData\\Roaming\\Python' (doesn't exist)
USER_SITE: 'C:\\Users\\RDCHLNRO\\AppData\\Roaming\\Python\\Python37\\site-packages' (doesn't exist)
ENABLE_USER_SITE: True

ArcPro 环境不是在其自己的站点包文件夹中查找,而是在默认环境的文件夹中查找。我无法解释为什么 conda 使用一组不同的包文件夹,具体取决于它从哪里启动。

我可以使用 sys.path.append 在脚本中添加那些丢失的路径,并且它能够找到丢失的包,但是导入一些包(numpy、scipy、matplotlib)会出现此错误:

ValueError: failed to parse CPython sys.version: '3.7.12 | packaged by conda-forge | (default, Oct 26 2021, 05:37:49) [MSC v.1916 64 bit (AMD64)]'

通过开始菜单启动的命令提示符导入包时不会出现此错误,仅在 ArcPro 启动的命令提示符中出现。

【问题讨论】:

    标签: python batch-file subprocess conda arcpy


    【解决方案1】:

    conda run 命令是在环境中执行特定代码的更惯用方式,无需管理交互式 shell。尝试类似:

    subprocess.Popen(“conda run -n myenv python C:\Users\RDCHLNRO\Desktop\waves2021\cc_ARC.py“.split(“ “))
    

    如果脚本具有交互性,您可能还需要 --live-stream 标志。

    【讨论】:

    • 我试过了,因为打开的 cmd 提示符不存在,所以我将 *.communicate() 的结果保存在 pkl 中,并在执行完成后查看。返回是(无,无)。如果我直接在打开的 cmd 提示符中尝试该命令,结果是“...conda: error: argument command: invalid selection:...”
    • @NO645 什么版本的 Conda?
    • 版本为 4.3.27
    猜你喜欢
    • 1970-01-01
    • 2019-01-20
    • 2016-07-16
    • 2018-06-14
    • 1970-01-01
    • 2020-11-09
    • 1970-01-01
    • 2018-07-04
    • 1970-01-01
    相关资源
    最近更新 更多