当前位置: 首页 > 知识库问答 >
问题:

为什么virtualenv从我的shell继承$PYTHONPATH?

沈运恒
2023-03-14

因此,我正在Ubuntu 14.04机器上将所有工具从python2迁移到python3.4。到目前为止,我已经完成了以下工作:

  1. 仅针对我的用户,在我的zshrc中将python别名为python3
  2. 在系统本身上安装了pip3(但无论如何我都会使用VirtualNVS,所以我不会真正使用它)
  3. 将我的VirtualNVRapper“make”别名更改为mkvirtualenv--python=/usr/bin/python3('workon'在下面被调用为'v')

奇怪的是,您可以在下面清楚地看到,从virtualenv激活的环境中运行python3仍然继承了我的$PYTHONPATH,它仍然是为我的所有python2路径设置的。在我的virtualenv中安装/运行程序时,这会造成严重破坏,因为python3路径显示在旧的python2路径之后,因此python2模块首先导入到我的程序中。在启动virtualenv之前将$PYTHONPATH置零为“”可以修复此问题,并且我的程序将按预期启动。但我的问题是:

  1. VirtualNVS中$PYTHONPATH的继承正常吗?这不是完全违背了目的吗?
    ○ echo $PYTHONPATH
    /usr/local/lib/python2.7/site-packages:/usr/local/lib/python2.7/dist-packages:/usr/lib/python2.7/dist-packages:/home/brian/dev

    brian@zeus:~/.virtualenvs
    ○ python2
    Python 2.7.6 (default, Mar 22 2014, 22:59:56)
    [GCC 4.8.2] on linux2
    Type "help", "copyright", "credits" or "license" for more information.
    >>> import sys, pprint
    >>> pprint.pprint(sys.path)
    ['',
     '/usr/local/lib/python2.7/dist-packages/pudb-2013.3.4-py2.7.egg',
     '/usr/local/lib/python2.7/dist-packages/Pygments-1.6-py2.7.egg',
     '/usr/local/lib/python2.7/dist-packages/urwid-1.1.1-py2.7-linux-x86_64.egg',
     '/usr/local/lib/python2.7/dist-packages/pythoscope-0.4.3-py2.7.egg',
     '/usr/local/lib/python2.7/site-packages',
     '/usr/local/lib/python2.7/dist-packages',
     '/usr/lib/python2.7/dist-packages',
     '/home/brian/dev',
     '/usr/lib/python2.7',
     '/usr/lib/python2.7/plat-x86_64-linux-gnu',
     '/usr/lib/python2.7/lib-tk',
     '/usr/lib/python2.7/lib-old',
     '/usr/lib/python2.7/lib-dynload',
     '/usr/lib/python2.7/dist-packages/PILcompat',
     '/usr/lib/python2.7/dist-packages/gst-0.10',
     '/usr/lib/python2.7/dist-packages/gtk-2.0',
     '/usr/lib/pymodules/python2.7',
     '/usr/lib/python2.7/dist-packages/ubuntu-sso-client',
     '/usr/lib/python2.7/dist-packages/ubuntuone-client',
     '/usr/lib/python2.7/dist-packages/ubuntuone-storage-protocol',
     '/usr/lib/python2.7/dist-packages/wx-2.8-gtk2-unicode']
    >>>

    brian@zeus:~/.virtualenvs
    ○ v py3venv
    (py3venv)
    brian@zeus:~/.virtualenvs
    ○ python3
    Python 3.4.0 (default, Apr 11 2014, 13:05:11)
    [GCC 4.8.2] on linux
    Type "help", "copyright", "credits" or "license" for more information.
    >>> import sys, pprint
    >>> pprint.pprint(sys.path)
    ['',
     '/usr/local/lib/python2.7/site-packages',
     '/usr/local/lib/python2.7/dist-packages',
     '/usr/lib/python2.7/dist-packages',
     '/home/brian/dev',
     '/home/brian/.virtualenvs/py3venv/lib/python3.4',
     '/home/brian/.virtualenvs/py3venv/lib/python3.4/plat-x86_64-linux-gnu',
     '/home/brian/.virtualenvs/py3venv/lib/python3.4/lib-dynload',
     '/usr/lib/python3.4',
     '/usr/lib/python3.4/plat-x86_64-linux-gnu',
     '/home/brian/.virtualenvs/py3venv/lib/python3.4/site-packages']
    >>>
    (py3venv)

共有3个答案

司马同
2023-03-14

$PYTHONPATH出现在您的virtualenv中,因为该virtualenv只是您的shell环境的一部分,您(在某处)告诉您的shell将PYTHONPATH的值导出到子shell。

在虚拟环境中工作的乐趣之一是,不需要在您的PYTHONPATH上放置额外的目录,但似乎您无意中一直将其视为全局(适用于所有shell)设置,而它更适合成为每个项目的设置。

海保臣
2023-03-14

我偶然发现了这个关于$PYTHONPATH的答案,它刚才为我解决了这个问题。本质上,设置$PYTHONPATH是可选的,对用户来说是一种方便。它应该只包含用户想要添加到他们的python路径的额外路径,这样用户就不必仅仅为了从终端运行脚本而在python中这样做。

所以为了解决上面的问题,我将$PYTHONPATH(在我的zshrc中)只设置为我的附加文件夹“$HOME/dev”,而不设置其他文件夹。这就消除了路径中对python2的引用,所有python3程序都在virtualenv中按预期启动。

方祺
2023-03-14

您还可以通过添加到virtualenv的/bin/activate文件来更改Pythonpath:

导出PYTHONPATH=“/your/path”

在此进一步解释:

报价:

要使其在停用时恢复到原始值,您可以添加

导出旧的_PYTHONPATH=“$PYTHONPATH”

在前面提到的行之前,并将以下行添加到bin/postde激活脚本中。

您可能还想看看这个答案,其中谈到使用add2virtualenv添加目录。

 类似资料:
  • 问题内容: 为什么以下代码不起作用(Python 2.5.2)? 我想创建一个类似的类,但具有不同的功能。显然我的函数永远不会被调用。而是调用原始文件并失败,因为它需要3个参数,而我传入了一个。 这里发生了什么?这是一个线索吗? 谢谢! 问题答案: 关于其他几个答案,这与用C本身实现的日期无关。该方法不做任何事情,因为它们是 不可变的 对象,因此构造函数()应该完成所有工作。您会看到相同的行为将i

  • 问题内容: 我有以下课程: 有没有搞错 ? 最糟糕的是我无法尝试super(),因为Exception是基于旧类的… 编辑:而且,是的,我试图切换继承/初始化的顺序。 EDIT2:我在Ubuntu8.10上使用CPython 2.4。您最近才知道这种信息很有用;-)。无论如何,这个小谜语已经让我的三个同事闭上了嘴。你会成为我今天最好的朋友… 问题答案: 两者和都在C中实现。 我认为您可以按照以下方

  • 下面的代码引发: 线程“main”java.lang.ClassCastException中的异常:不能将类子级转换为类java.util.List(子级位于加载器“app”的未命名模块中;java.util.List位于加载器“bootstrap”的模块java.base中) 我真的不知道它为什么会这样做。我想我写的代码是正确的。 请帮助我理解这一点,以及如何解决这个问题。

  • 问题内容: 我想创建一个以另一个为起点,这可能吗? 我必须记住用例: 假设我有两个用于生产,一个用于开发。开发环境需要与生产环境相同的程序包,但需要生产环境中不需要的其他程序包。我不想两次安装通用软件包。 例如,我想尝试一个软件包的开发版本。软件包的开发版本与稳定版本具有相同的要求。所以我创建了一个被称为并安装要求和稳定版本的文件。然后,我创建一个第二个调用并用作起点(用于需求),然后安装开发版本

  • 问题内容: 我正在尝试使用此命令安装Python软件包 我收到权限错误,不确定为什么。我可以使用来运行它,但是有人告诉我这是个坏主意,我应该改用virtualenv。 什么是虚拟环境?它对我有什么作用? 问题答案: 与系统Python和库一起运行会将您限制为OS提供商选择的一个特定Python版本。试图在一个Python安装上运行所有Python应用程序,可能会导致库集合之间发生版本冲突。对系统P

  • 为了便于DRY,我希望在父类中定义ContextConfiguration并让所有测试类继承它,如下所示: 父类: 子类: 根据ContextConfiguration文档,我应该能够继承父级的位置,但我不能让它工作。Spring仍然在默认位置()中查找文件,如果找不到,则会查找barfs。我尝试了以下方法,但没有成功: 使父类具体化 向父类添加无操作测试 同时向父类添加注入成员 以上组合 我使用