python -m <filename> <encoding>?

python -m <filename> <encoding>?

运行将python脚本作为模块时如何指定编码?

比如我想运行my_script.pypython -m my_script -utf8。但是没有这样的选择。相反,我应该在文件顶部提供 my_script.py 编码。它在某些 python-2.7 包中失败。

考虑下一个场景:

my_script.py:

# coding=utf-8
from pyglet.gl import *
  1. $ cd ~/Documents
  2. 创建非 ascii 文件夹:$ mkdir вафля
  3. $ cd вафля
  4. 使用上面的代码创建 my_script.py
  5. python my_script.py -- 效果不错
  6. python -m my_script -- 失败

工作站:Ubuntu 14.04.3 x64 + Python 2.7.6 x64(内置)

不要建议我打开Python 3.4,因为我已经打开了,只是想同时支持2.7和3.4版本的Python。

添加了回溯。

File "my_script.py", line 22, in <module>
    from pyglet.gl import *
  File "/usr/local/lib/python2.7/dist-packages/pyglet/gl/__init__.py", line 236, in <module>
    import pyglet.window
  File "/usr/local/lib/python2.7/dist-packages/pyglet/window/__init__.py", line 1817, in <module>
    gl._create_shadow_window()
  File "/usr/local/lib/python2.7/dist-packages/pyglet/gl/__init__.py", line 205, in _create_shadow_window
    _shadow_window = Window(width=1, height=1, visible=False)
  File "/usr/local/lib/python2.7/dist-packages/pyglet/window/xlib/__init__.py", line 163, in __init__
    super(XlibWindow, self).__init__(*args, **kwargs)
  File "/usr/local/lib/python2.7/dist-packages/pyglet/window/__init__.py", line 559, in __init__
    self._create()
  File "/usr/local/lib/python2.7/dist-packages/pyglet/window/xlib/__init__.py", line 353, in _create
    self.set_caption(self._caption)
  File "/usr/local/lib/python2.7/dist-packages/pyglet/window/xlib/__init__.py", line 511, in set_caption
    self._set_text_property('WM_NAME', caption, allow_utf8=False)
  File "/usr/local/lib/python2.7/dist-packages/pyglet/window/xlib/__init__.py", line 785, in _set_text_property
    buf = create_string_buffer(value.encode('ascii', 'ignore'))
UnicodeDecodeError: 'ascii' codec can't decode byte 0xd0 in position 19: ordinal not in range(128)

这似乎是 pyglet 中的错误。它使用 sys.argv[0] 作为其默认的 window 标题,但它希望标题字符串是 unicode 实例,稍后它可以 encode 为 ASCII(忽略 non-representable 统一码值)。但是,在 Python 2 中,sys.argv[0] 将是某种编码中的字节串(str 实例)(我不确定编码是否在任何地方指定,或者它是否可能因文件系统而异文件系统)。当您尝试 encode 一个已经编码的字节串时,Python 2 首先尝试使用 ascii 编解码器将字符串解码为 unicode object,然后再编码为请求。

只有在使用 -m 标志时才会看到这个错误,因为只有在那种情况下(在您测试的方式中)才会包含路径的 non-ASCII 部分 sys.argv[0]。当你调用 python my_script.py 时,sys.argv[0]"my_script.py"。当您使用 -m 时,sys.argv[0] 将是脚本文件(包括 non-ASCII 文件夹)的绝对路径。

我不确定正确的修复方法到底是什么,因为正如我上面提到的,我不确定 sys.argv 使用的编码在 Python 2 中是否有明确规定。如果你只想为你的系统解决这个问题,你可以只更改 pyglet/window/__init__.py 中的这些行(它们应该大致是第 555-556 行):

        if caption is None:
            caption = sys.argv[0]

收件人:

        if caption is None:
            caption = sys.argv[0].decode("utf8")