将Unicode文本写入文本文件?

sim*_*mon 219 python unicode character-encoding python-2.x

我正在从Google文档中提取数据,处理数据并将其写入文件(最终我将粘贴到Wordpress页面).

它有一些非ASCII符号.如何将这些安全地转换为可以在HTML源中使用的符号?

目前我正在将所有内容转换为Unicode,在Python字符串中将它们连接在一起,然后执行:

import codecs
f = codecs.open('out.txt', mode="w", encoding="iso-8859-1")
f.write(all_html.encode("iso-8859-1", "replace"))
Run Code Online (Sandbox Code Playgroud)

最后一行有编码错误:

UnicodeDecodeError:'ascii'编解码器无法解码位置12286中的字节0xa0:序数不在范围内(128)

部分解决方案:

这个Python运行时没有错误:

row = [unicode(x.strip()) if x is not None else u'' for x in row]
all_html = row[0] + "<br/>" + row[1]
f = open('out.txt', 'w')
f.write(all_html.encode("utf-8"))
Run Code Online (Sandbox Code Playgroud)

但是如果我打开实际的文本文件,我会看到许多符号,如:

Qur’an 
Run Code Online (Sandbox Code Playgroud)

也许我需要写一些文本文件以外的东西?

qua*_*oic 314

通过在第一次获取unicode对象时将其解码为unicode对象并在出路时根据需要对其进行编码,尽可能多地处理unicode对象.

如果你的字符串实际上是一个unicode对象,你需要在将它写入文件之前将其转换为unicode编码的字符串对象:

foo = u'?, ?, ?, ? ?, ?, ?, ?, ?, and ?.'
f = open('test', 'w')
f.write(foo.encode('utf8'))
f.close()
Run Code Online (Sandbox Code Playgroud)

当您再次读取该文件时,您将获得一个可以解码为unicode对象的unicode编码字符串:

f = file('test', 'r')
print f.read().decode('utf8')
Run Code Online (Sandbox Code Playgroud)

  • 我需要打开二进制模式,即 f=open('test', 'wb'),如 /sf/answers/385969951/ 中所述 - 否则我会得到“TypeError: write() argument必须是 str,而不是 bytes” (6认同)
  • 这个答案可能应该包括 @david_n_lee 答案中的 `open('filename', 'w',encoding='utf-8')` (对于 python 3) (6认同)

jfs*_*jfs 68

在Python 2.6+中,你可以在Python 3上使用io.open()它是默认的(内置open()):

import io

with io.open(filename, 'w', encoding=character_encoding) as file:
    file.write(unicode_text)
Run Code Online (Sandbox Code Playgroud)

如果您需要以增量方式编写文本(不需要unicode_text.encode(character_encoding)多次调用),这可能会更方便.与codecs模块不同,io模块具有适当的通用换行支持.

  • 这也适用于Python 3(显而易见,但仍值得指出). (2认同)

dav*_*lee 31

Unicode字符串处理在Python 3中标准化.

  1. Char以Unicode存储
  2. 您只需要在utf-8中打开文件

    out1 = "(???? ???????????????? )"
    fobj = open("t1.txt", "w", encoding="utf-8")
    fobj.write(out1)
    fobj.close()
    
    Run Code Online (Sandbox Code Playgroud)

  • 这就是答案。这就是正确将 utf-8 写入文件的方法,谢谢! (2认同)

Tho*_*ers 18

打开的文件codecs.open是一个文件,它接收unicode数据,对其进行编码并将其iso-8859-1写入文件.但是,你试着写的不是unicode; 你需要unicode在编码它iso-8859-1 自己.这就是unicode.encode方法的作用,编码unicode字符串的结果是一个bytestring(一个str类型).

您应该使用normal open()并自己编码unicode,或者(通常是更好的主意)使用codecs.open()不是自己编码数据.


Aar*_*all 16

前言:你的观众会工作吗?

确保您的查看器/编辑器/终端(无论您是否与utf-8编码文件交互)都可以读取该文件.这在Windows上经常出现问题,例如记事本.

将Unicode文本写入文本文件?

在Python 2时,使用open从所述io模块(这是相同的内建open在Python 3):

import io
Run Code Online (Sandbox Code Playgroud)

通常,最佳实践UTF-8用于写入文件(我们甚至不必担心使用utf-8的字节顺序).

encoding = 'utf-8'
Run Code Online (Sandbox Code Playgroud)

utf-8是最现代和普遍可用的编码 - 它适用于所有Web浏览器,大多数文本编辑器(如果有问题,请参阅您的设置)和大多数终端/ shell.

在Windows上,utf-16le如果您仅限于在记事本(或其他受限查看器)中查看输出,则可以尝试.

encoding = 'utf-16le' # sorry, Windows users... :(
Run Code Online (Sandbox Code Playgroud)

然后用上下文管理器打开它并写出你的unicode字符:

with io.open(filename, 'w', encoding=encoding) as f:
    f.write(unicode_object)
Run Code Online (Sandbox Code Playgroud)

使用许多Unicode字符的示例

下面是一个示例,尝试将每个可能的字符映射到三位宽(4是最大值,但这有点远)从数字表示(整数)到编码的可打印输出,以及它的名称,如果可能(把它放到一个叫做的文件中uni.py):

from __future__ import print_function
import io
from unicodedata import name, category
from curses.ascii import controlnames
from collections import Counter

try: # use these if Python 2
    unicode_chr, range = unichr, xrange
except NameError: # Python 3
    unicode_chr = chr

exclude_categories = set(('Co', 'Cn'))
counts = Counter()
control_names = dict(enumerate(controlnames))
with io.open('unidata', 'w', encoding='utf-8') as f:
    for x in range((2**8)**3): 
        try:
            char = unicode_chr(x)
        except ValueError:
            continue # can't map to unicode, try next x
        cat = category(char)
        counts.update((cat,))
        if cat in exclude_categories:
            continue # get rid of noise & greatly shorten result file
        try:
            uname = name(char)
        except ValueError: # probably control character, don't use actual
            uname = control_names.get(x, '')
            f.write(u'{0:>6x} {1}    {2}\n'.format(x, cat, uname))
        else:
            f.write(u'{0:>6x} {1}  {2}  {3}\n'.format(x, cat, char, uname))
# may as well describe the types we logged.
for cat, count in counts.items():
    print('{0} chars of category, {1}'.format(count, cat))
Run Code Online (Sandbox Code Playgroud)

这应该以大约一分钟的顺序运行,您可以查看数据文件,如果您的文件查看器可以显示unicode,您将看到它.有关类别的信息可以在这里找到.根据计数,我们可以通过排除没有与之关联的符号的Cn和Co类别来改进我们的结果.

$ python uni.py
Run Code Online (Sandbox Code Playgroud)

它将显示十六进制映射,类别,符号(除非无法获取名称,因此可能是控制字符),以及符号的名称.例如

我建议less在Unix或Cygwin上使用(不要将整个文件打印/输出到输出中):

$ less unidata
Run Code Online (Sandbox Code Playgroud)

例如,将显示类似于我使用Python 2(unicode 5.2)从中采样的以下行:

     0 Cc NUL
    20 Zs     SPACE
    21 Po  !  EXCLAMATION MARK
    b6 So  ¶  PILCROW SIGN
    d0 Lu  Ð  LATIN CAPITAL LETTER ETH
   e59 Nd  ?  THAI DIGIT NINE
  2887 So  ?  BRAILLE PATTERN DOTS-1238
  bc13 Lo  ?  HANGUL SYLLABLE MIH
  ffeb Sm  ?  HALFWIDTH RIGHTWARDS ARROW
Run Code Online (Sandbox Code Playgroud)

我的Anaconda的Python 3.5有unicode 8.0,我认为大多数都是3.