如何在python magic编码说明符行中指定扩展的ascii(即range(256))?

gre*_*red 11 python encoding templates wsgi mako

我正在使用mako模板生成专门的配置文件.其中一些文件包含扩展的ASCII字符(> 127),但mako扼流圈说当我使用时字符超出范围:

## -*- coding: ascii -*-
Run Code Online (Sandbox Code Playgroud)

所以我想知道是否有类似的东西:

## -*- coding: eascii -*-
Run Code Online (Sandbox Code Playgroud)

我可以使用它可以使用范围(128,256)字符.

编辑:

这是文件的违规部分的转储:

000001b0  39 c0 c1 c2 c3 c4 c5 c6  c7 c8 c9 ca cb cc cd ce  |9...............|
000001c0  cf d0 d1 d2 d3 d4 d5 d6  d7 d8 d9 da db dc dd de  |................|
000001d0  df e0 e1 e2 e3 e4 e5 e6  e7 e8 e9 ea eb ec ed ee  |................|
000001e0  ef f0 f1 f2 f3 f4 f5 f6  f7 f8 f9 fa fb fc fd fe  |................|
000001f0  ff 5d 2b 28 27 73 29 3f  22 0a 20 20 20 20 20 20  |.]+('s)?".      |
00000200  20 20 74 6f 6b 65 6e 3a  20 57 4f 52 44 20 20 20  |  token: WORD   |
00000210  20 20 22 5b 41 2d 5a 61  2d 7a 30 2d 39 c0 c1 c2  |  "[A-Za-z0-9...|
00000220  c3 c4 c5 c6 c7 c8 c9 ca  cb cc cd ce cf d0 d1 d2  |................|
00000230  d3 d4 d5 d6 d7 d8 d9 da  db dc dd de df e0 e1 e2  |................|
00000240  e3 e4 e5 e6 e7 e8 e9 ea  eb ec ed ee ef f0 f1 f2  |................|
00000250  f3 f4 f5 f6 f7 f8 f9 fa  fb fc fd fe ff 5d 2b 28  |.............]+(|
Run Code Online (Sandbox Code Playgroud)

mako抱怨的第一个字符是000001b4.如果我删除此部分,一切正常.插入部分后,mako抱怨:

UnicodeDecodeError: 'ascii' codec can't decode byte 0xc3 in position 19: ordinal not in range(128)
Run Code Online (Sandbox Code Playgroud)

无论我在魔术评论栏中使用'ascii'还是'latin-1',都是一样的抱怨.

谢谢!

格雷格

wbe*_*rry 16

简短的回答

使用cp437作为一些复古DOS乐趣的编码.除127之外的所有大于或等于32十进制的字节值都映射到此编码中的可显示字符.然后使用cp037作为真正有趣时间的编码.然后问问自己,你怎么知道其中哪一个,如果其中任何一个是"正确的".

答案很长

你必须忘掉一些东西:字节值和字符的绝对等价.

当今许多基本的文本编辑器和调试工具,以及Python语言规范,都意味着字节和字符之间的绝对等价,而实际上并不存在.这是不正确的,74 6f 6b 65 6e "令牌".仅对于ASCII兼容的字符编码,此对应关系有效.在今天仍然很常见的EBCDIC中,"令牌"对应于字节值a3 96 92 85 95.

因此,虽然Python 2.6解释器愉快地评估'text' == u'text'True,但它不应该,因为它们只是在ASCII或兼容编码的假设下是等价的,即便如此,它们也不应被视为相等.(至少'\xfd' == u'\xfd'False并且在尝试时会给你一个警告.)Python 3.1评估'text' == b'text'False.但是,即使解释器接受这个表达式也意味着字节值和字符的绝对等价,因为表达式的b'text'意思是" 'text'解释器应用ASCII编码时得到的字节串".

据我所知,目前广泛使用的每种编程语言都在其设计的某处隐含使用ASCII或ISO-8859-1(Latin-1)字符编码.在C中,char数据类型实际上是一个字节.我看到一个Java 1.4 VM,其中构造函数java.lang.String(byte[] data)采用ISO-8859-1编码.大多数编译器和解释器都假设源代码的ASCII或ISO-8859-1编码(有些可以让你改变它).在Java中,字符串长度实际上是UTF-16代码单元长度,对于字符U+10000及以上字符来说可能是错误的.在Unix中,文件名是根据终端设置解释的字节字符串,允许您使用open('a\x08b', 'w').write('Say my name!').

因此,我们所有人都受到了我们学会信任的工具的训练和条件,相信'A' 0x41.但事实并非如此.'A'是一个字符,0x41是一个字节,它们根本不相等.

一旦你在这一点上开悟了,你就可以毫无困难地解决你的问题.您只需确定软件中的哪个组件假定这些字节值的ASCII编码,以及如何更改该行为或确保显示不同的字节值.

PS:短语"扩展ASCII"和"ANSI字符集"是用词不当.