Python unicode在命令行中写入文件崩溃但在IDE中没有

时间:2012-03-22 12:51:52

标签: python unicode aptana pydev

我遇到一个问题,我的Python 2.7.3rc2代码通过IDE(带PyDev的Aptana Studio 3)运行良好,但是当我双击.py文件或尝试从Windows命令运行它时崩溃线。

问题在于我尝试将包含unicode字符的字符串写入文件。 IDE没有问题,并使用unicode字符正确写入文件。命令行版本抱怨它无法编码某些字符。

问题的根源是:IDE版本与正确编写unicode文件而另一个版本没有的命令行版本有什么不同?

理想的解决方案应该让命令行版本与IDE版本完全相同。


编辑:抱歉,我认为我假设使用哪个命令将字符串写入文件,但我是Python的新手。实际命令write()在对象f上调用,该对象已使用f = open(path, 'w')进行实例化。我传递了我希望它写入文件的字符串,该字符串包含unicode字符。

完整的错误消息是:

Traceback (most recent call last):
  File "writer.py", line 46, in <module>
    write_listings(c, output_path)
  File "writer.py", line 33, in write_listings
    print name
  File "c:\Python27\lib\encodings\cp437.py", line 12, in encode
    return codecs.charmap_encode(input,errors,encoding_map)
UnicodeEncodeError: 'charmap' codec can't encode characters in position 21-26: character maps to <undefined>

这是一个示例字符串: 滑鐵盧安大略加拿大

不幸的是我在创建SSCCE时遇到了麻烦,因为我不能将该字符串文字放入源代码文件中,而不会抱怨我没有声明编码。令人沮丧的是 - 当我从IDE运行所有东西时,这一切都运转得很好,现在我正朝着一个unicode兔子洞走去!

编辑:感谢Fredrik,我现在能够制作一个SSCCE。这是:

# -*- coding: utf-8 -*-
str = u'滑鐵盧安大略加拿大'
f = open('test', 'w')
f.write(str)
f.close()

从命令行运行时,此SSCCE崩溃,但IDE中的为什么?

编辑:我添加了一些由Edward Loper建议的额外代码,以验证Python的版本与命令行和IDE版本完全相同。

这是新代码:

# -*- coding: utf-8 -*-
import sys
print sys.version
print open
print open.__module__

str = u'滑鐵盧安大略加拿大'
f = open('test', 'w')
f.write(str)
f.close()

以下是从IDE运行时的输出:

2.7.3rc2 (default, Mar 18 2012, 22:59:27) [MSC v.1500 64 bit (AMD64)]
<built-in function open>
__builtin__

以下是从命令行运行时的输出:

2.7.3rc2 (default, Mar 18 2012, 22:59:27) [MSC v.1500 64 bit (AMD64)]
<built-in function open>
__builtin__
Traceback (most recent call last):
  File "test.py", line 9, in <module>
    f.write(str)
UnicodeEncodeError: 'ascii' codec can't encode characters in position 0-8: ordinal not in range(128)

在我看来,问题仍然没有答案,因为我仍然不知道什么会使它在IDE中运行而不是命令行!

3 个答案:

答案 0 :(得分:3)

在将字符串写入文件之前,您应该以所需的编码对字符串进行显式编码:

f.write(text.encode("cp1250", "replace")) # Czech Windows encoding, use your own

f.write(text.encode("utf-8", "replace")) # UTF-8

您还可以使用特定编码显式打开文件:

# -*- coding: utf-8 -*-
from __future__ import unicode_literals
import codecs

x = "abcč"
f = codecs.open("test.txt", "w", "utf-8", "replace")
f.write(x)

答案 1 :(得分:1)

每当我需要使用特定编码时,我就会这样做

#!/usr/bin/env python
# -*- coding: UTF-8 -*-
import codecs
out = codecs.getwriter('utf-8')(sys.stdout)
out.write('some åäö-string')

答案 2 :(得分:1)

正如Fenikso所说,你应该在将字符串写入文件之前对其进行编码。 file.write()本身不这样做的原因是您需要指定要使用的编码(utf-8,utf-16等)。有一个python模块“codecs”,它允许您创建知道要使用的编码的流对象,并自动应用它。这就是Fenikso在他的第二个例子中使用的。

至于为什么你的代码在IDE中运行而不是命令行,我的猜测是你的IDE正在将“默认编码”设置为某个非默认值。尝试在IDE和命令行中运行它,看它是否有所不同:

>>> import sys
>>> print sys.getdefaultencoding()

以下是一些相关信息:http://blog.ianbicking.org/illusive-setdefaultencoding.html