Supervisor 执行时报 UnicodeError

2016-11-15 04:06:57 +08:00
 SP00F

报错信息:

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 则报错。

2075 次点击
所在节点    Python
13 条回复
janxin
2016-11-15 08:06:28 +08:00
python2 请加 magic encoding
est
2016-11-15 09:28:11 +08:00
第一个 LANG 写错了
glasslion
2016-11-15 10:11:12 +08:00
明明是代码的 bug , 通过改 locale 去修正就有点缘木求鱼了

print (u"[!] 休眠检查时间 %s" % CurrentTime()).encode('utf-8)
Sylv
2016-11-15 10:43:08 +08:00
尝试设置环境变量 PYTHONIOENCODING=UTF-8
SP00F
2016-11-15 16:45:22 +08:00
@glasslion 时间这里我转成了 str ,转的时间格式没问题。。。本地以及在 shell 执行都没问题,在 Supervisor 启动就报错了。
当我把所有中文内容换成英语后在 Supervisor 上启动。。。没有问题……与代码无关
SP00F
2016-11-15 17:00:02 +08:00
@janxin 头已加 encoding 啦
glasslion
2016-11-15 18:38:27 +08:00
@SP00F 还真就是代码的问题,在本地和 shell 没问题, 是因为你的 shell 的 locale 设置成了 utf-8 。
但程序本身不应该依赖这种环境变量, 不然把程序移植到其他环境,或是用另一种方式启动程序, 就报错了
SP00F
2016-11-17 06:56:57 +08:00
@glasslion thx 非常感谢,还真是这个问题 -。-
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
2016-11-23 10:13:56 +08:00
@Arthur2e5 你倒是说说怎么判定执行环境的 encoding ?
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
2016-11-24 10:10:55 +08:00
@Arthur2e5 别人把 stdout 重定向到文件,怎么判定?重新到 less/more 怎么判定? 还是要猜。 btw, _Py_device_encoding 也是猜的, 并不能保证准确
Arthur2e5
2016-11-25 02:08:29 +08:00
@glasslion 所以我一直在说的“猜错了就给它掰回去”你是两层回复就忘了?

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

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

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

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

© 2021 V2EX