简体   繁体   English

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

[英]Why does virtualenv inherit $PYTHONPATH from my shell?

So I'm migrating all my tools from python2 to python3.4 on an Ubuntu 14.04 machine. 所以我在Ubuntu 14.04机器上将我的所有工具从python2迁移到python3.4。 So far I've done the following: 到目前为止,我已经完成了以下工作:

  1. aliased python to python3 in my zshrc for just my user 在我的zshrc中为我的用户使用python到python3
  2. installed pip3 on the system itself (but I'll just be using virtualenvs for everything anyway so I won't really use it) 在系统本身上安装了pip3(但我只是将virtualenvs用于所有内容,所以我不会真正使用它)
  3. changed my virtualenvwrapper "make" alias to mkvirtualenv --python=/usr/bin/python3 ('workon' is invoked below as 'v') 将我的virtualenvwrapper“make”别名改为mkvirtualenv --python=/usr/bin/python3 ('workon'在下面被调用为'v')

Now curiously, and you can clearly see it below, running python3 from a virtualenv activated environment still inherits my $PYTHONPATH which is still setup for all my python2 paths. 现在好奇,你可以清楚地看到它,从virtualenv激活的环境运行python3仍然继承我的$ PYTHONPATH,它仍然为我所有的python2路径设置。 This wreaks havoc when installing/running programs in my virtualenv because the python3 paths show up AFTER the old python2 paths, so python2 modules are imported first in my programs. 这在我的virtualenv中安装/运行程序时会造成严重破坏,因为python3路径显示在旧的python2路径之后,因此python2模块首先在我的程序中导入。 Nulling my $PYTHONPATH to '' before starting the virtualenv fixes this and my programs start as expected. 在启动virtualenv之前将我的$ PYTHONPATH取消为''修复此问题并且我的程序按预期启动。 But my questions are: 但我的问题是:

  1. Is this inheritance of $PYTHONPATH in virtualenvs normal? 在virtualenvs中这个$ PYTHONPATH的继承是正常的吗? Doesn't that defeat the entire purpose? 这不是打败了整个目的吗?
  2. Why set $PYTHONPATH as an env-var in the shell when python already handles it's own paths internally? 当python已经在内部处理它自己的路径时,为什么将$ PYTHONPATH设置为shell中的env-var?
  3. Am I using $PYTHONPATH correctly? 我正确使用$ PYTHONPATH吗? Should I just be setting it in my 'zshrc' to only list my personal additions ($HOME/dev) and not the redundant '/usr/local/lib/' locations? 我应该只在我的'zshrc'中设置它以仅列出我的个人添加物($ HOME / dev)而不是冗余的'/ usr / local / lib /'位置?
  4. I can very easily export an alternate python3 path for use with my virtualenvs just before invoking them, and reset them when done, but is this the best way to fix this? 在调用它们之前,我可以非常轻松地导出备用python3路径以供我的virtualenvs使用,并在完成后重置它们,但这是解决此问题的最佳方法吗?
○ 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)

You can also change the Pythonpath by adding to your virtualenv's /bin/activate file: 您还可以通过添加到virtualenv的/ bin / activate文件来更改Python路径:

export PYTHONPATH="/your/path" export PYTHONPATH =“/ your / path”

Further explained here : 进一步解释在这里

Quote: 引用:

To have it restored to its original value on deactivate, you could add 要在停用时将其恢复为原始值,您可以添加

export OLD_PYTHONPATH="$PYTHONPATH" export OLD_PYTHONPATH =“$ PYTHONPATH”

before the previously mentioned line, and add the following line to your bin/postdeactivate script. 在前面提到的行之前,将以下行添加到bin / postdeactivate脚本中。


You might also want to have a look at this answer which talks about using add2virtualenv for adding directories. 您可能还想查看答案, 答案讨论使用add2virtualenv添加目录。

I stumbled onto this answer about $PYTHONPATH which solved this for me just now. 我偶然发现了这个关于$ PYTHONPATH的答案 ,它刚才为我解决了这个问题。 Essentially, setting $PYTHONPATH is optional and is a convenience to the user. 基本上,设置$ PYTHONPATH是可选的,对用户来说是方便的。 It should only contain additional paths the user wants to add to their python path so that the user doesn't have to do this in python itself just to run a script from the terminal. 它应该只包含用户想要添加到其python路径的其他路径,以便用户不必在python本身中执行此操作只是为了从终端运行脚本。

So to solve my problem above, I set my $PYTHONPATH (in my zshrc) to only my additional folder of '$HOME/dev' and nothing else. 因此,要解决上面的问题,我将$ PYTHONPATH(在我的zshrc中)设置为仅我的'$ HOME / dev'的附加文件夹,而不是其他任何内容。 This eliminated the references to python2 in my path and all my python3 programs are starting as expected in my virtualenv. 这消除了我的路径中对python2的引用,我的所有python3程序都按照我的virtualenv中的预期开始。

The $PYTHONPATH appears in your virtualenv because that virtualenv is just a part of your shell environment, and you (somewhere) told your shell to export the value of PYTHONPATH to child shells. $PYTHONPATH出现在你的virtualenv中因为virtualenv只是你的shell环境的一部分,你(某处)告诉你的shell将PYTHONPATH的值导出到子shell。

One of the joys of working in virtual environments is that there is much less need to put additional directories on your PYTHONPATH , but it appears as though you have unwittingly been treating it as a global (for all shells) setting, when it's more suited to being a per-project setting. 在虚拟环境中工作的乐趣之一就是不需要在PYTHONPATH上添加额外的目录,但看起来好像你已经无意中将它视为全局(对于所有shell)设置,当它更适合于作为每个项目的设置。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM