Sublime 3 用 Ctrl+B 运行打印中文就报错是什么原因?

2016-04-07 23:40:07 +08:00
 pimin

如图,右边是 sublimerepl,输出正常
下面是 CTRL+B 运行结果

PS.折腾几天上了黑苹果,CTRL=COMMAND
5326 次点击
所在节点    问与答
14 条回复
pimin
2016-04-07 23:43:11 +08:00
我好想发现问题了,pyenv 对 sublime 没有生效
pimin
2016-04-07 23:48:35 +08:00
手动切换到系统版本发现还是可以输出中文,为什么 Sublime 就报错呢
Sylv
2016-04-08 01:31:00 +08:00
在 Python 3 下发生这个问题还是有点奇怪的,很有可能是你的 Sublime Text 的环境变量 PYTHONIOENCODING 被设置为 ascii 了,运行以下命令检查下:
print("sys.stdout.encoding", sys.stdout.encoding)
print("PYTHONIOENCODING", os.environ.get('PYTHONIOENCODING'))

在默认情况下,以上命令在 Sublime Text 里用 Python 3 运行的结果是以下:
sys.stdout.encoding UTF-8
PYTHONIOENCODING None

相关参考:
/t/163786
pimin
2016-04-08 01:47:12 +08:00
@Sylv
如果不设置 PYTHONIOENCODING 打印 sys.stdout.encoding 输出是 US-ASCII
按你说的在 build 添加 PYTHONIOENCODING 定义为 uft-8 之后 sys.stdout.encoding 也变成 utf-8 了
好文已收藏
pimin
2016-04-08 02:16:58 +08:00
@Sylv
顺便请教下,sublime 有没有办法切换 Python 版本啊
除了改 build 这个笨办法
目前情况学习用的 Python3,但是线上我用的 PaaS ACE 和 BCE 的云服务只支持 py2.
现在是通过 brew 安装了 Python3,自建了一个 build 用 Python3 可以运行.
安装了 pyenv 不知道怎么让编辑器支持,目前只是 shell 环境可以切换.
Sylv
2016-04-08 02:41:58 +08:00
我是把 Python.sublime-build 里的 shell_cmd 的 python 改为了 pyenv 的 python 路径:
"shell_cmd": "/Users/user/.pyenv/shims/python -u \"$file\""

这样在终端里运行 pyenv global <version> 后,/Users/user/.pyenv/shims/python 的 Python 版本也就会相应改变, Sublime Text 中运行的 Python 版本也就跟着变了。

这种办法还是有一定缺陷的,例如无法自动识别 virtualenv 环境,可能还有更好的解决办法。
imn1
2016-04-08 08:56:46 +08:00
开发 py2 不是该用 st2 么?
pimin
2016-04-09 17:57:14 +08:00
@Sylv
找到了比较好的解决版本的方案
Anaconda 插件可以自动调整路径
安装之后通过 pyenv local <version>就可以直接切换版本
不需要额外设置
Sylv
2016-04-10 16:25:30 +08:00
@pimin 我试了下,貌似 Anaconda 对我这不起作用。


我研究了下,如果不改 sublime-build 里的命令,要想让 Sublime Text 识别出 pyenv 切换的 Python 版本,则需要把 pyenv 的 shims 路径(/Users/<user>/.pyenv/shims )添加到 Sublime Text 的 PATH 环境变量中。

我试了几种办法修改 Sublime Text 的 PATH 环境变量,但每次 "/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin" 这几个路径都会在 Sublime Text 的 PATH 里优先于我设置的 pyenv 路径,使得 Sublime Text 只会去使用我安装在 /usr/local/bin/ 的 Python 版本,无法通过 pyenv 来切换版本。

最后发现,发生这种情况其实是因为 /etc/paths 文件里设置的路径对于 Sublime Text 3 是优先权最高的,而默认的 /etc/paths 内容为:
/usr/local/bin
/usr/bin
/bin
/usr/sbin
/sbin
所以导致 "/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin" 这几个路径总会位于 Sublime Text 的 PATH 环境变量的最前面。

因此设置 Sublime Text 3 的 PATH 环境变量的正确方法应当是去修改 /etc/paths 文件。

我把 pyenv 的 shims 路径(/Users/<user>/.pyenv/shims )添加到了 /etc/paths 文件的首行后, Sublime Text 3 就能正确识别出 pyenv global/local 命令切换的 Python 版本了,不再需要修改 sublime-build 或安装其它插件。

并且此方法另外的好处是,其它有依赖 Python 版本的插件(例如: Sublime ​ REPL 、 Sublime ​ Code ​ Intel 、 Python Flake ​ 8 Lint 等)也能自动识别出 pyenv 切换的 Python 版本,不再需要去修改它们的配置文件来指向正确的 Python 解释器了。


以上,把这个问题的解决方法写在这,供后人参考,少走一些弯路。
pimin
2016-04-10 16:45:03 +08:00
@Sylv
Anaconda 内置有环境变量设置
我现在没在电脑前,等下试着改为 /Users/<user>/.pyenv/shims 看下是否生效
设置之后影响也是全局的
对 sublimerepl 之类插件也是生效的
在插件里设置好处是方便备份,切换环境比较容易
当然改环境变量不依赖插件,对于不用这个插件的人也更有意义
mark 下,晚上更
pimin
2016-04-11 20:33:40 +08:00
我确认了下,我的 paths 里面环境变量是默认的:
/usr/local/bin
/usr/bin
/bin
/usr/sbin
/sbin

在 shell 因为执行了 pyenv 初始化命令,所以 echo $PATH 输出为:
/Volumes/nan/.pyenv/shims:
/usr/local/bin:
/usr/bin:
/bin:
/usr/sbin:
/sbin

然后我禁用了 Anaconda 发现 pyenv 还是总是生效..
确认环境变量改变并不是因为 Anaconda
经过排查之后确认,是因为改动.bashprofile 影响的 sublime
我的.bashprofile 内容是:
if which pyenv > /dev/null; then eval "$(pyenv init -)"; fi
export CLICOLOR=1export
export SVN_EDITOR=vim
LSCOLORS=gxfxaxdxcxegedabagacad

以上,感觉折腾半天是开始时候 pyenv 初始化没处理好的问题
pimin
2016-04-11 20:34:09 +08:00
@Sylv 更新了下,在楼上,忘记召唤了
Sylv
2016-04-12 03:54:05 +08:00
@pimin
感谢回复,终于让我知道为什么在我这 Sublime Text 的 PATH 一直不正确了。
因为我用的 shell 是 zsh 而没有用 bash ,所以我的各种环境变量设置命令是写在 .zshrc 文件里而不是 .bash_profile 文件里。这样看来 Sublime Text 其实是会去读取 .bash_profile 文件的,但不会去读 .zshrc 。
所以真正正确的解决办法应该是把 .zshrc 里的设置命令复制一份到 .bash_profile 里,这样 Sublime Text 就能正确识别各种环境变量了,而不用去更改系统默认的 /etc/paths 文件了。
Sylv
2016-04-12 04:58:18 +08:00
@pimin
我又多试了下,发现识别 .bash_profile 文件只是插件级的行为,只会对 Build System 和 Sublime REPL 等部分插件有效,但一些插件如 Sublime Code ​ Intel 和 Python Flake 8 Lint 等并不会去读取 .bash_profile 文件,实际上 Sublime Text 全局级别的 PATH 还是只受 /etc/paths 影响。
可以通过 ctrl+` 快捷键唤出 Sublime Text 的 console ,然后输入以下命令来查看全局的 PATH 环境变量:
import os; os.environ['PATH']

所以,总结一下:
如果只需要 Build System 和 Sublime REPL 能识别出 pyenv 切换的 Python 版本,那么只用把 pyenv 的 eval "$(pyenv init -)" 命令添加到 .bash_profile 文件中就可以了。
但如果想要能对 Sublime Text 的全部插件都生效,还是需要把 pyenv 的 shims 路径(/Users/<user>/.pyenv/shims )添加到 /etc/paths 文件首行。

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/269405

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX