【问题标题】:Encoding issue with printing the degree symbol on a word document using docx使用 docx 在 word 文档上打印度数符号的编码问题
【发布时间】:2013-08-06 22:15:10
【问题描述】:

尝试使用python docx将度数符号添加到word文档中,我的函数定义如下:

def convert_decimal_degrees2DMS(self,value):
    #value = math.fabs(value)
    degrees = int(value)
    submin = math.fabs( (value - int(value) ) * 60)
    minutes = int(submin)
    subseconds = round(math.fabs((submin-int(submin)) * 60),1)
    subseconds = int(subseconds)
    self.angle = str(degrees) + " Degrees " + str(minutes) + " Minutes " +\
               str(subseconds)[0:2] + " Seconds "
    #self.angle = str(degrees) + "-" + str(minutes) + "-" + str(subseconds)
    #return str(degrees) + "-" + str(minutes) + "-" + str(subseconds)
    #degree = u'\N{DEGREE SIGN}'.encode('utf-8')
    return "{0}{1}{2}'{3}''".format(degrees,u'°'.encode('cp1252'),minutes,subseconds)

我不断收到的错误是:

  File "lxml.etree.pyx", line 921, in lxml.etree._Element.text.__set__ (src\lxml\lxml.etree.c:41467)
  File "apihelpers.pxi", line 652, in lxml.etree._setNodeText (src\lxml\lxml.etree.c:18888)
  File "apihelpers.pxi", line 1335, in lxml.etree._utf8 (src\lxml\lxml.etree.c:24701)
ValueError: All strings must be XML compatible: Unicode or ASCII, no NULL bytes or control characters
Exception AttributeError: "'NoneType' object has no attribute 'print_exc'" in <function _remove at 0x01E0F770> ignored

我尝试了很多变化,但没有任何效果,我担心这可能是因为我对编码缺乏了解,我没有得到这个。

【问题讨论】:

  • 函数返回的是我添加到word文档中的内容。

标签: python python-2.7 ms-word


【解决方案1】:

u'°'.encode('cp1252') 返回一个等于'\xb0' 的字节串(str 类型)。同样,在其他地方,您正在将内容转换为 str。该错误告诉您您需要unicode(Unicode 代码点)而不是str(字节)类型的字符串。度数符号本身可能不是问题。

解决方案是简单地提供 Unicode 字符串:所以u'°' 而不是u'°'.encode('cp1252'),并且

self.angle = degrees + u" Degrees " + minutes + u" Minutes " + \
               subseconds[0:2] + u" Seconds "

而不是

self.angle = str(degrees) + " Degrees " + str(minutes) + " Minutes " +\
               str(subseconds)[0:2] + " Seconds "

(假设 degrees 等的类型是 unicode 而不是 str)。请注意 Unicode 字符串的 u'' 语法,而不是字节字符串的 '' 语法。

关于在 Python 源代码中包含非 ASCII 字符,您必须记住的一件事是 PEP-0263 中记录的编码标头。所以你会在 shebang 后面加上一个编码声明:

#!/usr/bin/python
# -*- coding: UTF-8 -*-

请记住,使用 PEP 0263 并不会神奇地消除 strunicode 的二元性。 '°' 将是在磁盘上的源代码文件中找到的任何 str(字节字符串),因此长度不一定为 1(如果 ISO-8859-1,它等效于 '\xb0',如果 DOS cp437,到'\xf8',如果是 UTF-8,则为 '\xc2\xb0')。而u'°' 将是Unicode 代码点U+00B0,无论源代码的编码如何。

这是源代码中非 ASCII 字符的示例。对于这个例子来说,查看源代码的实际字节很重要。源代码是UTF-8编码的,所以'°'的长度为2;毕竟是字节串。

$ cat x.py 
#!/usr/bin/python
# -*- coding: UTF-8 -*-

print repr('°')
print len('°')
print len(u'°')

$ od -c -txC x.py
0000000    #   !   /   u   s   r   /   b   i   n   /   p   y   t   h   o
           23  21  2f  75  73  72  2f  62  69  6e  2f  70  79  74  68  6f
0000020    n  \n   #       -   *   -       c   o   d   i   n   g   :    
           6e  0a  23  20  2d  2a  2d  20  63  6f  64  69  6e  67  3a  20
0000040    U   T   F   -   8       -   *   -  \n  \n   p   r   i   n   t
           55  54  46  2d  38  20  2d  2a  2d  0a  0a  70  72  69  6e  74
0000060        r   e   p   r   (   '   °  **   '   )  \n   p   r   i   n
           20  72  65  70  72  28  27  c2  b0  27  29  0a  70  72  69  6e
0000100    t       l   e   n   (   '   °  **   '   )  \n   p   r   i   n
           74  20  6c  65  6e  28  27  c2  b0  27  29  0a  70  72  69  6e
0000120    t       l   e   n   (   u   '   °  **   '   )  \n            
           74  20  6c  65  6e  28  75  27  c2  b0  27  29  0a
$ python x.py
'\xc2\xb0'
2
1

【讨论】:

    猜你喜欢
    • 2021-01-02
    • 1970-01-01
    • 1970-01-01
    • 2023-03-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-06-20
    相关资源
    最近更新 更多