V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
推荐学习书目
Learn Python the Hard Way
Python Sites
PyPI - Python Package Index
http://diveintopython.org/toc/index.html
Pocoo
值得关注的项目
PyPy
Celery
Jinja2
Read the Docs
gevent
pyenv
virtualenv
Stackless Python
Beautiful Soup
结巴中文分词
Green Unicorn
Sentry
Shovel
Pyflakes
pytest
Python 编程
pep8 Checker
Styles
PEP 8
Google Python Style Guide
Code Style from The Hitchhiker's Guide
SP00F
V2EX  ›  Python

Supervisor 执行时报 UnicodeError

  •  
  •   SP00F · 2016-11-15 04:06:57 +08:00 · 2062 次点击
    这是一个创建于 2726 天前的主题,其中的信息可能已经有所发展或是发生改变。

    报错信息:

    Traceback (most recent call last):
      File "/home/wwwroot/Spider/run.py", line 143, in <module>
        Spider.run()
      File "/home/wwwroot/Spider/run.py", line 53, in run
        print u"[!] 休眠检查时间 %s" % CurrentTime()
    UnicodeEncodeError: 'ascii' codec can't encode characters in position 4-7: ordinal not in range(128)
    

    在 shell 中直接运行则无报错。爬了 Google 和 stackoverflow ,尝试过在 Supervisor 配置文件中添加下列内容,无效!依旧报错

    environment=LANG="en_US.utf8", LC_ALL="en_US.UTF-8", LC_LANG="en_US.UTF-8"
    

    最后 export LANG 依旧无效,代码中有有设置 #coding:utf-8 ,在 Windows 下运行正常, Linux 上 shell 运行也没问题,但是用 Supervisor 则报错。

    13 条回复    2016-11-25 02:08:29 +08:00
    janxin
        1
    janxin  
       2016-11-15 08:06:28 +08:00 via iPhone
    python2 请加 magic encoding
    est
        2
    est  
       2016-11-15 09:28:11 +08:00
    第一个 LANG 写错了
    glasslion
        3
    glasslion  
       2016-11-15 10:11:12 +08:00
    明明是代码的 bug , 通过改 locale 去修正就有点缘木求鱼了

    print (u"[!] 休眠检查时间 %s" % CurrentTime()).encode('utf-8)
    Sylv
        4
    Sylv  
       2016-11-15 10:43:08 +08:00 via iPhone
    尝试设置环境变量 PYTHONIOENCODING=UTF-8
    SP00F
        5
    SP00F  
    OP
       2016-11-15 16:45:22 +08:00
    @glasslion 时间这里我转成了 str ,转的时间格式没问题。。。本地以及在 shell 执行都没问题,在 Supervisor 启动就报错了。
    当我把所有中文内容换成英语后在 Supervisor 上启动。。。没有问题……与代码无关
    SP00F
        6
    SP00F  
    OP
       2016-11-15 17:00:02 +08:00
    @janxin 头已加 encoding 啦
    glasslion
        7
    glasslion  
       2016-11-15 18:38:27 +08:00   ❤️ 1
    @SP00F 还真就是代码的问题,在本地和 shell 没问题, 是因为你的 shell 的 locale 设置成了 utf-8 。
    但程序本身不应该依赖这种环境变量, 不然把程序移植到其他环境,或是用另一种方式启动程序, 就报错了
    SP00F
        8
    SP00F  
    OP
       2016-11-17 06:56:57 +08:00
    @glasslion thx 非常感谢,还真是这个问题 -。-
    Arthur2e5
        9
    Arthur2e5  
       2016-11-23 01:09:29 +08:00
    Python2 的 print 对于字符串( unicode )类型需要在内部按照 Python 感知到自己应该使用的 IO 编码方式编码,才能输出到缓冲区之类的东西。如果 Python 的感觉不对,那你就该用 PYTHONIOENCODING=UTF-8 这种东西掰对。

    @glasslion 一个语言本来打印语句可以直接打印字符串的,结果却要变成字节流打印,难道不是执行环境的 bug 吗?更别说:

    * 依赖环境变量?直接假定输出代码页是 UTF-8 岂不是更糟?能编码中文、运行 Python 的终端窗口用的编码又不止 UTF-8 。
    * 字节串 print 这件事情基本上是 Python2 没想好 Unicode 字符串和字节串区别的时候留下的黑历史, Py3 去试试 print(b'\x2e') 就知道了。
    glasslion
        10
    glasslion  
       2016-11-23 10:13:56 +08:00
    @Arthur2e5 你倒是说说怎么判定执行环境的 encoding ?
    Arthur2e5
        11
    Arthur2e5  
       2016-11-24 09:29:33 +08:00
    @glasslion 真是,怎么就不能判定了?

    就拿 Python 2.7 ( https://github.com/python/cpython/tree/c188c1d )举 sys.stdout 的例子:
    https://github.com/python/cpython/blob/c188c1d/Python/pythonrun.c#L342
    就酱。别的系统的实现也在那附近。

    // Python 3.x 的实现在 _Py_device_encoding() 里面, GitHub 网页上用 GetConsoleOutputCP 也能搜到。
    // 对于 locale 有 GetACP()。

    我用 cp437 开个 Python 2.7 :
    C:\Program Files (x86)\FontForgeBuilds\bin>ffpython.exe
    Python 2.7.10 (default, Jul 8 2015, 15:14:56)
    [GCC 5.1.0] on win32
    Type "help", "copyright", "credits" or "license" for more information.
    >>> import sys, locale, os
    >>> print(sys.stdout.encoding)
    cp437
    >>> print(sys.stdout.isatty())
    True

    我 chcp 936 再开一个:

    >>> print(sys.stdout.encoding)
    cp936

    * Python 3.6 的官方 Windows 构建 sys.stdout.encoding 都是 utf_8 了,我也懒得去看是什么鬼。
    glasslion
        12
    glasslion  
       2016-11-24 10:10:55 +08:00
    @Arthur2e5 别人把 stdout 重定向到文件,怎么判定?重新到 less/more 怎么判定? 还是要猜。 btw, _Py_device_encoding 也是猜的, 并不能保证准确
    Arthur2e5
        13
    Arthur2e5  
       2016-11-25 02:08:29 +08:00
    @glasslion 所以我一直在说的“猜错了就给它掰回去”你是两层回复就忘了?
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   我们的愿景   ·   实用小工具   ·   1356 人在线   最高记录 6543   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 34ms · UTC 16:49 · PVG 00:49 · LAX 09:49 · JFK 12:49
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.