【问题标题】:Python encoding problems on startup script in Raspberry Pi debianRaspberry Pi debian 中启动脚本上的 Python 编码问题
【发布时间】:2016-03-14 00:09:25
【问题描述】:

所以我有一个运行 Debian 的 Raspberry Pi 和 WebIOPi system。当我使用标准启动“$ sudo /etc/init.d/webiopi start”命令启动它时,守护程序运行良好,但自动启动不起作用“$ sudo update-rc.d webiopi defaults”。

日志表明这是 Python 中的编码问题,我猜 python 使用的是 ascii,但脚本文件使用的是 utf8。

为什么它可以正常工作但不能自动启动,有什么好的方法可以解决这个问题?

【问题讨论】:

  • 确切的错误信息是什么?
  • @flo 遗憾的是我没有经常访问 Pi,但它沿着这条线'ascii' codec can't encode character **** in position **: ordinal not in range(128)

标签: python-2.7 encoding raspberry-pi debian webiopi


【解决方案1】:

为了确认日志和您的怀疑,这是一个编码问题(最有可能是字节与字符串)。即使您使用 # -*- coding: utf-8 -*- 将文件的编码设置为 UTF-8,在处理已从一种形式更改为另一种形式的文本时仍然会遇到问题。

字符串并不是真正的字符串,而是以特定顺序表示的字节。 UTF-8 提供了比 ASCII 可以处理的更多字符的编码,因此如果您尝试将 UTF-8 编码字符串中存在的字符转换为 ASCII 编码字符串,那么您将收到错误,因为不存在这样的编码.

如果没有更多信息,例如代码和/或数据源,我无法给出更好的答案。

阅读https://docs.python.org/2/howto/unicode.html#the-unicode-type,我们通过学习以下示例来学习:

>>> unicode('abcdef')
u'abcdef'
>>> s = unicode('abcdef')
>>> type(s)
<type 'unicode'>
>>> unicode('abcdef' + chr(255))    
Traceback (most recent call last):
...
UnicodeDecodeError: 'ascii' codec can't decode byte 0xff in position 6:
ordinal not in range(128)

文档还提到,您可以选择通过替换或忽略它们来处理这些异常,如下所示:

>>> unicode('\x80abc', errors='strict')     
Traceback (most recent call last):
    ...
UnicodeDecodeError: 'ascii' codec can't decode byte 0x80 in position 0:
ordinal not in range(128)
>>> unicode('\x80abc', errors='replace')
u'\ufffdabc'
>>> unicode('\x80abc', errors='ignore')
u'abc'

注意 1:在 Python 3 中,情况发生了变化。对于编写与 Python 3 兼容的代码,我建议阅读以下内容:

https://docs.python.org/3.0/whatsnew/3.0.html#text-vs-data-instead-of-unicode-vs-8-bit

注意 2:还值得注意的是,如果在尝试在控制台上显示字符串时遇到编码问题,python 有一个 -u 开关,可以在某些情况下使用,例如当您通过 CGI 脚本提供二进制文件时,这将关闭字符串的缓冲,但这会打开另一个蠕虫罐。但是,尽管如此,在不调用 -u 的情况下模仿这种行为:

>>> print 'test'
'test'
>>> import os
>>> import sys
>>> sys.stdout = os.fdopen(sys.stdout.fileno(), 'w', 0)
>>> print 'test'
test

【讨论】:

    【解决方案2】:

    这真的取决于那个程序。

    但是,如果手动启动它和作为系统启动的一部分启动它有区别,那么核心区别应该在环境变量。这典型的例如inittab.

    这里有两个选项 - 您的 locale 未设置,或者脚本最终使用不同版本的 python

    对于较早的版本,请考虑将LANG(精确)或LC_ALL(锤子)添加到此脚本或全局环境中以执行所有启动任务。

    您可以通过比较这两个调用来手动尝试:

    sudo LC_ALL=en_US.UTF-8 /etc/init.d/webiopi start
    

    对比

    sudo LC_ALL=C /etc/init.d/webiopi start
    

    对于后者,请尝试将 PATH 更改为仅包含部分 /bin:/usr/bin:/usr/local/bin

    【讨论】:

      猜你喜欢
      • 2019-09-20
      • 1970-01-01
      • 2014-11-07
      • 2015-08-11
      • 1970-01-01
      • 1970-01-01
      • 2012-09-14
      • 2021-05-03
      • 2021-10-09
      相关资源
      最近更新 更多