从Eclipse内部运行Python脚本时PyDev搞乱编码设置

时间:2017-08-21 14:44:06

标签: python eclipse encoding pydev ros

我尝试使用subprocess.Popen()运行以下命令:

ros_version_retrieve = subprocess.Popen(["rosversion", "-d"], shell=False, stdout=subprocess.PIPE)
ros_version_retrieve.wait()

rosversion是ROS的一部分,允许通过调用rosversion <package>来检索给定包的版本,或者通过调用rosversion -d来检索已安装ROS的版本。在第一种情况下,我将得到一个像1.12.3的字符串,在第二种情况下,我得到kinetic(因为这是我目前正在使用的版本)。

我从终端启动Eclipse,以便在IDE中也可以使用PATH和其他几个变量:

  • PYTHONPATH /usr/local/lib/python2.7/dist-packages:/home/user/catkin_ws/devel/lib/python2.7/dist-packages:/opt/ros /kinetic/lib/python2.7/dist-packages:/usr/local/lib/python3.5/dist-packages/:/opt/OpenCV/python/3.4:/opt/OpenCV/python/2.7:/opt/ ROS /靛蓝/ LIB / python2.7 / DIST-封装
  • PATH /opt/Qts/5.9/bin:/opt/QtCreator-custom/bin:/usr/local/bin:/opt/MATLAB/R2012a/bin /:/ home /用户/斌:/ home / user中/ catkin_ws /脚本中:/ opt / ROS /运动/斌:/ home / user中/斌:在/ usr / local / sbin中:在/ usr / local / bin目录:/ usr / sbin目录:/ USR /bin:/sbin:/bin:/usr/games:/usr/local/games:/opt/Qts/5.9/bin:/snap/bin:/usr/lib/jvm/java-9-oracle/bin: / usr / lib中/ JVM / JAVA -9- ORACLE /分贝/ bin中

我知道它非常不整洁(我刚刚了解了virtualenv)但它到目前为止没有任何问题。

当我从PyDev(Eclipse Neon)内部运行第一行同样的代码时,我得到了

  

致命Python错误:Py_Initialize:无法获取语言环境编码
  文件&#34; /usr/lib/python2.7/encodings/ init .py&#34;,第123行       提出CodecRegistryError,\

     

^ SyntaxError:语法无效

我也尝试使用特定的包

来调用rosversion
subprocess.Popen(["rosversion", "roscpp"], shell=False, stdout=subprocess.PIPE)

但我得到了同样的错误。这两个命令调用在我的终端中没有任何问题,并且当我在PyDev之外调用我的脚本时也是如此。

我已按照this问题寻找答案。取消设置我的PYTHONPATH,然后在我的代码中手动设置它不是一个选项。我也非常确定找到命令,因为我的代码中有多个其他位置,我调用rospack基本上它提供的每个参数的组合,它工作得很好。从我的PyDev项目的错误和设置中我也确定正确的解释器被称为Python 2.7而不是3.4,我也在我的系统上。

由于这似乎(至少在我的情况下)是一个PyDev问题,而不是系统范围的问题,我正在寻找一个解决方案,我不必改变我的脚本只是为了能够在PyDev中运行它。如果我需要设置项目设置,请告诉。

更新

感谢下面的答案。但是弹出PYTHONPATH导致rosversion失败,但这次是由于无法在内部导入rospkg(这是通过PYTHONPATH加载的ROS环境的一部分)。我的代码中没有任何地方import rospkg,因为这违背了我正在做的事情的目的 - 一个甚至可以设置ROS的外部配置工具,如果我导入的话,这是不可能的并使用属于它的模块。

我的PYTHONHOME实际上是空的。如果我只添加建议的编码部分,则会发生与以前相同的错误 - PyInitializeCodecRegistryError等等。

再次 - 如果我从bash启动它,脚本可以正常运行。它只在我从PyDev运行时失败。

2 个答案:

答案 0 :(得分:0)

我认为问题在于您在配置中混合了Python 2和Python 3路径。

即:来自您的PYTHONPATH

/usr/local/lib/python2.7/dist-packages 
/home/user/catkin_ws/devel/lib/python2.7/dist-packages <-- py2
/opt/ros/kinetic/lib/python2.7/dist-packages
/usr/local/lib/python3.5/dist-packages/  <- py3
/opt/OpenCV/python/3.4:/opt/OpenCV/python/2.7 
/opt/ros/indigo/lib/python2.7/dist-packages <-- py2

我认为为了安全起见,您应该创建所需的环境并将其传递给子进程调用,正确填写密钥:

  • PYTHONPATH
  • PYTHONHOME
  • PYTHONIOENCODING
  • PYTHONUNBUFFERED

东西:

env = os.environ.copy()
env.pop('PYTHONPATH', None)
env.pop('PYTHONHOME', None)
env['PYTHONIOENCODING'] = 'ascii'
env['PYTHONUNBUFFERED'] = '1'
subprocess.Popen(["rosversion", "-d"], env=env)

也许PATHLANG也可以添加到该列表中(不确定,这很大程度上取决于您启动的内容以及您使用的程序将读取的变量)。< / p>

答案 1 :(得分:0)

我刚试了一些东西并且它有效 - 我的Popen()的命令列表如下所示:["python2.7", "/usr/local/bin/rosversion", "-d"]并且它有效!

由于访问GitHub时出现问题,我实际上无法访问source code of rosversion,尽管我很盲目,不能通过查看rospkg导入失败的错误来自己得出结论。

rospack不同rosversion是一个Python脚本。虽然在bash shell中调用它不会导致问题,但似乎在子进程中运行它需要我实际调用该子进程内的Python解释器并传递绝对路径(我可以使用which rosversion获取)。