V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
V2EX 提问指南
pimin
V2EX  ›  问与答

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

  •  
  •   pimin · 2016-04-07 23:40:07 +08:00 · 5447 次点击
    这是一个创建于 3176 天前的主题,其中的信息可能已经有所发展或是发生改变。

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

    PS.折腾几天上了黑苹果,CTRL=COMMAND
    14 条回复    2016-04-12 04:58:18 +08:00
    pimin
        1
    pimin  
    OP
       2016-04-07 23:43:11 +08:00
    我好想发现问题了,pyenv 对 sublime 没有生效
    pimin
        2
    pimin  
    OP
       2016-04-07 23:48:35 +08:00
    手动切换到系统版本发现还是可以输出中文,为什么 Sublime 就报错呢
    Sylv
        3
    Sylv  
       2016-04-08 01:31:00 +08:00   ❤️ 1
    在 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
        4
    pimin  
    OP
       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
        5
    pimin  
    OP
       2016-04-08 02:16:58 +08:00
    @Sylv
    顺便请教下,sublime 有没有办法切换 Python 版本啊
    除了改 build 这个笨办法
    目前情况学习用的 Python3,但是线上我用的 PaaS ACE 和 BCE 的云服务只支持 py2.
    现在是通过 brew 安装了 Python3,自建了一个 build 用 Python3 可以运行.
    安装了 pyenv 不知道怎么让编辑器支持,目前只是 shell 环境可以切换.
    Sylv
        6
    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
        7
    imn1  
       2016-04-08 08:56:46 +08:00
    开发 py2 不是该用 st2 么?
    pimin
        8
    pimin  
    OP
       2016-04-09 17:57:14 +08:00   ❤️ 1
    @Sylv
    找到了比较好的解决版本的方案
    Anaconda 插件可以自动调整路径
    安装之后通过 pyenv local <version>就可以直接切换版本
    不需要额外设置
    Sylv
        9
    Sylv  
       2016-04-10 16:25:30 +08:00   ❤️ 1
    @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
        10
    pimin  
    OP
       2016-04-10 16:45:03 +08:00 via Android
    @Sylv
    Anaconda 内置有环境变量设置
    我现在没在电脑前,等下试着改为 /Users/<user>/.pyenv/shims 看下是否生效
    设置之后影响也是全局的
    对 sublimerepl 之类插件也是生效的
    在插件里设置好处是方便备份,切换环境比较容易
    当然改环境变量不依赖插件,对于不用这个插件的人也更有意义
    mark 下,晚上更
    pimin
        11
    pimin  
    OP
       2016-04-11 20:33:40 +08:00   ❤️ 1
    我确认了下,我的 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
        12
    pimin  
    OP
       2016-04-11 20:34:09 +08:00
    @Sylv 更新了下,在楼上,忘记召唤了
    Sylv
        13
    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
        14
    Sylv  
       2016-04-12 04:58:18 +08:00   ❤️ 2
    @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 文件首行。
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   3124 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 29ms · UTC 13:10 · PVG 21:10 · LAX 05:10 · JFK 08:10
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.