【问题标题】:Python - temporarily change default encoding?Python - 临时更改默认编码?
【发布时间】:2021-02-21 11:51:59
【问题描述】:

我想使用https://pypi.org/project/pyclibrary/ 来解析一些.h 文件。

不幸的是,其中一些 .h 文件不是 UTF-8 编码的 - Notepad++ 告诉我它们是“ANSI”编码的(因为它们起源于 Windows,我猜这意味着 CP-1252?不确定......)

无论如何,我可以将问题简化为这个例子:

mytest.h:

/*******************************************************
Just a test header file
© Copyright myself
*******************************************************/

#ifndef _MY_TEST_
#define _MY_TEST_
#endif

这里棘手的部分是版权字符 - 只是为了确保,这里有一个 hexdump:

$ hexdump -C mytest.h
00000000  2f 2a 2a 2a 2a 2a 2a 2a  2a 2a 2a 2a 2a 2a 2a 2a  |/***************|
00000010  2a 2a 2a 2a 2a 2a 2a 2a  2a 2a 2a 2a 2a 2a 2a 2a  |****************|
*
00000030  2a 2a 2a 2a 2a 2a 2a 2a  0d 0a 4a 75 73 74 20 61  |********..Just a|
00000040  20 74 65 73 74 20 68 65  61 64 65 72 20 66 69 6c  | test header fil|
00000050  65 0d 0a a9 20 43 6f 70  79 72 69 67 68 74 20 6d  |e... Copyright m|
00000060  79 73 65 6c 66 0d 0a 2a  2a 2a 2a 2a 2a 2a 2a 2a  |yself..*********|
00000070  2a 2a 2a 2a 2a 2a 2a 2a  2a 2a 2a 2a 2a 2a 2a 2a  |****************|
*
00000090  2a 2a 2a 2a 2a 2a 2a 2a  2a 2a 2a 2a 2a 2a 2f 0d  |**************/.|
000000a0  0a 0d 0a 23 69 66 6e 64  65 66 20 5f 4d 59 5f 54  |...#ifndef _MY_T|
000000b0  45 53 54 5f 0d 0a 23 64  65 66 69 6e 65 20 5f 4d  |EST_..#define _M|
000000c0  59 5f 54 45 53 54 5f 0d  0a 23 65 6e 64 69 66 0d  |Y_TEST_..#endif.|
000000d0  0a                                                |.|
000000d1

然后我试试这个 Python 脚本:

mytest.py

#!/usr/bin/env python3

import sys, os
from pyclibrary import CParser

myhfile = "mytest.h"
c_parser = CParser([myhfile])
print(c_parser)

当我运行它时,我得到:

$ python3 mytest.py
Traceback (most recent call last):
  File "mytest.py", line 7, in <module>
    c_parser = CParser([myhfile])
  File "/usr/lib/python3.8/site-packages/pyclibrary/c_parser.py", line 443, in __init__
    self.load_file(f, replace)
  File "/usr/lib/python3.8/site-packages/pyclibrary/c_parser.py", line 678, in load_file
    self.files[path] = fd.read()
  File "/usr/lib/python3.8/codecs.py", line 322, in decode
    (result, consumed) = self._buffer_decode(data, self.errors, final)
UnicodeDecodeError: 'utf-8' codec can't decode byte 0xa9 in position 83: invalid start byte

...我猜,“第 83 位的字节 0xa9”是版权字符。所以,我的看法:

  • 我真的没有选择 pyclibrary 中的文件编码的选项 - 但我也不想破解 pyclibrary
  • 我也不想编辑 .h 文件,并让它们与 UTF-8 兼容

...所以,我唯一能想到的就是将 Python 的默认编码(打开文件时)更改为 ANSI/CP-1252/whatever,only 用于调用到c_parser = CParser([myhfile]) - 然后恢复默认的UTF-8。

这有可能以某种方式做到吗?我见过Changing default encoding of Python? - 但那里的大多数答案似乎暗示,你最好只在脚本开始时更改一次默认编码 - 我找不到任何关于临时更改默认编码的参考,然后恢复原来的 UTF-8 以后默认。

【问题讨论】:

    标签: python-3.x encoding utf-8


    【解决方案1】:

    好的,我想我明白了 - 找到了这个帖子:Windows Python: Changing encoding using the locale module - 并受到启发尝试使用 locale 包;请注意,我在 Windows 上使用 MSYS2 bash,因此,我使用 MSYS2 Python3。所以,现在文件是:

    mytest.py

    #!/usr/bin/env python3
    
    import sys, os
    import locale
    from pyclibrary import CParser
    import pprint
    
    myhfile = "mytest.h"
    print( locale.getlocale() ) # ('en_US', 'UTF-8')
    #pprint.pprint(locale.locale_alias)
    locale.setlocale( locale.LC_ALL, 'en_US.ISO8859-1' )
    
    c_parser = CParser([myhfile])
    print(c_parser)
    
    locale.setlocale( locale.LC_ALL, 'en_US.UTF-8' )
    print( locale.getlocale() ) # ('en_US', 'UTF-8')
    

    ...运行它会产生:

    $ python3 mytest.py
    ('en_US', 'UTF-8')
    ============== types ==================
    {}
    ============== variables ==================
    {}
    ============== fnmacros ==================
    {}
    ============== macros ==================
    {'_MY_TEST_': ''}
    ============== structs ==================
    {}
    ============== unions ==================
    {}
    ============== enums ==================
    {}
    ============== functions ==================
    {}
    ============== values ==================
    {'_MY_TEST_': None}
    
    ('en_US', 'UTF-8')
    

    嗯 - 这对我来说看起来不错......

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2013-10-18
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-01-23
      • 1970-01-01
      相关资源
      最近更新 更多