Anaconda 当安装的包使用conda虚拟环境时,如何使Python控制台脚本入口点工作?
问题- 从非虚拟环境切换到conda虚拟环境会导致无法识别控制台脚本入口点 背景- 我最近试图了解如何在Python项目中使用虚拟环境。在macOS Catalina的更新导致我所有的PyCharm项目显示无效的解释器错误后,我决定这样做。两天后,我终于可以再次运行一个脚本了——这是我碰到过的最糟糕的一堵砖墙。我在任何地方都找不到解决方案,所以我写下了我的第一个so问题和接下来的解决方案,我想我可能终于有了一些值得为这个我用了这么久的网站做出贡献的东西 我的设置Anaconda 当安装的包使用conda虚拟环境时,如何使Python控制台脚本入口点工作?,anaconda,virtualenv,setuptools,packaging,entry-point,Anaconda,Virtualenv,Setuptools,Packaging,Entry Point,问题- 从非虚拟环境切换到conda虚拟环境会导致无法识别控制台脚本入口点 背景- 我最近试图了解如何在Python项目中使用虚拟环境。在macOS Catalina的更新导致我所有的PyCharm项目显示无效的解释器错误后,我决定这样做。两天后,我终于可以再次运行一个脚本了——这是我碰到过的最糟糕的一堵砖墙。我在任何地方都找不到解决方案,所以我写下了我的第一个so问题和接下来的解决方案,我想我可能终于有了一些值得为这个我用了这么久的网站做出贡献的东西 我的设置 OS:macOS Catali
- OS:macOS Catalina
- Shell:bash(是的,我在Catalina更新后将其更改回去,并抑制了唠叨的“zsh现在是默认值”消息)
- IDE:PyCharm 19.1 Pro
- 蟒蛇:4.4.7
- Python:3.7
My_Machine:my_package my_user_name$ pip install -e .
我使用setuptools的setup.py文件创建python包,并使用PyCharm进行构建。在setup.py文件中,我定义了如下控制台脚本入口点:
setup.py:
# -*- coding: utf-8 -*-
from setuptools import setup, find_packages
setup(...
name='my_project',
entry_points={'console_scripts':['my_entry_name=my_package.scripts.my_python_script:main'
]},
...
)
在转移到conda虚拟环境之前,多年来我一直通过如下批处理文件完美地运行脚本:
我的批处理文件。命令:
#!/bin/bash
cd "$(dirname "$0")" # set the working directory as the command file locations
my_entry_name <script arguments>
#!/usr/bin/env bash
echo "VERIFY: Python version BEFORE activating virtual environment:"
which python
echo "Activating conda virtual environment..."
source activate my_env_name
echo "Setting python version to use in this environment..."
#!/Users/my_username/anaconda3/envs/my_env_name/bin/python
echo "VERIFY: Python version AFTER activating virtual environment:"
which python
cd "$(dirname "$0")" # set the working directory as the command file locations
echo "RUN THE SCRIPT:"
my_entry_name <script arguments>
#/bin/bash
cd“$(dirname“$0”)”#将工作目录设置为命令文件位置
我的名字
但是,在切换到conda虚拟环境后,运行命令文件会产生my_entry\u name:command not found
错误
迄今为止尝试过的事情
- 通过
terminal命令验证并尝试设置使用哪个python。我可以看到默认值是which python
,如果我在项目中的命令提示符下执行此操作,我会看到/Users/my_user\u name/anaconda3/bin/python
,反映出预期的环境版本/Users/my_user\u name/anaconda3/envs/my_env/bin/python
- 检查
中的实际入口点文件,查看shebang行如何指示python版本,即/Users/my_user_name/anaconda3/envs/my_env/bin/my_entry_name
#/Users/my_user_name/anaconda3/envs/my_env/bin/python
- 尝试将此shebang添加到.command文件的顶部
- 多次重新安装我的软件包,认为入口点可能没有正确注册
- 在bash和zsh之间经常乱搞,认为通过Catalina更新转换到zsh,然后返回bash可能会造成问题
- 试图通过从虚拟环境返回来恢复功能,但无法使PyCharm非虚拟解释器设置再次工作
- 查看$PATH内容中的问题
- 阅读大量有关虚拟环境的教程(我所发现的一切仅限于基础知识)
- 追踪与虚拟环境相关的setuptools中的bug
- 这些努力的许多组合
所有这些都不起作用-相同的
my\u entry\u name:command not found
错误。非常令人沮丧的两天。经过两天的努力,我找到了一个解决方案,我将在下面发布,但是我非常希望听到评论、备选方案和直接的“你是个白痴”教育
似乎有两个要素是必要的:
- 指示要用作与虚拟环境相关联的python版本(正如我尝试过的,没有成功)
- 激活虚拟环境
#!/bin/bash
cd "$(dirname "$0")" # set the working directory as the command file locations
my_entry_name <script arguments>
#!/usr/bin/env bash
echo "VERIFY: Python version BEFORE activating virtual environment:"
which python
echo "Activating conda virtual environment..."
source activate my_env_name
echo "Setting python version to use in this environment..."
#!/Users/my_username/anaconda3/envs/my_env_name/bin/python
echo "VERIFY: Python version AFTER activating virtual environment:"
which python
cd "$(dirname "$0")" # set the working directory as the command file locations
echo "RUN THE SCRIPT:"
my_entry_name <script arguments>
#/usr/bin/env bash
echo“在激活虚拟环境之前验证:Python版本:”
哪条蟒蛇
echo“激活conda虚拟环境…”
源激活我的环境名称
echo“设置在此环境中使用的python版本…”
#!/Users/my_username/anaconda3/envs/my_env_name/bin/python
echo“验证:激活虚拟环境后的Python版本:”
哪条蟒蛇
cd“$(dirname“$0”)”#将工作目录设置为命令文件位置
echo“运行脚本:”
我的名字
我缺少的关键一行是源代码激活我的环境名称
。我验证了删除此项会导致失败,并且每次都必须包含此项,而不是仅包含一次,因此必须包含在我的.command文件中
我也不清楚多个shebang行是否可以,但这很好
我很高兴能再次发挥作用,但我不得不承认,我很沮丧,因为这种体系结构不仅使我的入门点工作,而且没有这种笨重。拥有入口点的原因是允许脚本使用者轻松调用它,而不必关心脚本的位置和安装方式等细节。虚拟环境的使用似乎消除了这些入口点的便利。我完全赞成使用虚拟环境的好处,但是有没有什么方法可以让我既吃蛋糕又吃蛋糕呢?理想情况下,调用入口点将激活虚拟环境,并知道要使用哪个版本的python。有没有更好的方法可以做到这一点呢?您不必激活Python虚拟环境,一次也不必激活。假设您在
/venv
有一个虚拟环境,然后,您可以随时随地调用/venv/bin/python
或/venv/bin/my_entry_name
,而无需激活虚拟环境
/anaconda3/bin/my_entry_name
#!/bin/bash
cd "$(dirname "$0")" # set the working directory as the command file locations
entry_point_name <my script args>