【python修改open函数默认编码】Linux locale、COCO修改默认编码、报错: UnicodeDecodeError: ‘ascii‘ codec can‘t decode byte

本文介绍了一种解决使用COCO库时遇到的UTF-8编码问题的方法,通过重写_getpreferredencoding函数,使得在读取json文件时能够正确处理UTF-8编码。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

0 开门见山

在文件开头加上如下代码即可【强行】修改encoding

import _bootlocale
_bootlocale.getpreferredencoding = lambda do_setlocale = True : "utf-8"

1 前言

当我们想使用utf-8编码打开一个json或其他文件的时候, 会使用:

import json
f = open('abc.json', 'r', encoding='utf-8')
j = json.load(f)

十分简单方便, 但是使用第三方COCO库时, 我们只能调用: 

coco_api = COCO(json_file)


## 如下为COCO构造函数:
class COCO:
    def __init__(self, annotation_file=None):
        """
        Constructor of Microsoft COCO helper class for reading and visualizing annotations.
        :param annotation_file (str): location of annotation file
        :param image_folder (str): location to the folder that hosts images.
        :return:
        """
        # load dataset
        self.dataset,self.anns,self.cats,self.imgs = dict(),dict(),dict(),dict()
        self.imgToAnns, self.catToImgs = defaultdict(list), defaultdict(list)
        if not annotation_file == None:
            print('loading annotations into memory...')
            tic = time.time()
            with open(annotation_file, 'r') as f:
                dataset = json.load(f)

其中的open是被写死的, 调用utf-8编码的文件就会报错:

<stderr>:UnicodeDecodeError: 'ascii' codec can't decode byte 0xe2 in position 724090: ordinal not in range(128)

 所以我们要通过一些方法修改open函数的默认打开方式

2 locale

2.1 其他的显示默认编码方法

笔者调研了众多显示默认/修改默认编码的方法, 有的博客说python3默认就是utf-8, 有的说:

PYTHONIOENCODING=utf-8 python abc.py

python -X utf-8 abc.py

import sys 
print(sys.platform) 
print(sys.getdefaultencoding()) 


import locale 
print(locale.getpreferredencoding())  

提供了四种方法, 而然前三种方法均无效, 使用过后还是会报 

UnicodeDecodeError: 'ascii' codec can't decode byte  的错误

只有第四种, 会显示

encoding='ANSI_X3.4-1968'

让笔者找到了希望, 于是便从修改第四种方法的默认值改起:

2.2 locale概述

locale 是 Linux 系统中多语言环境的设置接口,在 Linux 中,使用 locale 命令来设置和显示程序运行的语言环境,locale 会根据计算机用户所使用的语言,所在国家或者地区,以及当地的文化传统定义一个软件运行时的语言环境。locale 由ANSI C提供支持。

这位兄弟写的很详细:  

优快云: LINUX locale指令

 

3 修改默认Encoding

既然

import locale 
print(locale.getpreferredencoding()) 

返回值是ANSI_X3.4-1968, 我们便从getpreferredencoding() 函数下手

查看 locale.py源码编发便可发现, 其实是调用的 _bootlocale.getpreferredencoding() , 而且根据各个平台的不同自动构建;

且返回值也就是一个简单的string.

我们想想办法可以直接重写函数 "_bootlocale.getpreferredencoding", 让其无论如何返回值都为 "UTF-8"

还好python万物皆引用,

直接赋值一个小匿名函数即可:

import _bootlocale
_bootlocale.getpreferredencoding = lambda do_setlocale = True : "utf-8"

 

 完美解决! 

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

蜗牛小瀚

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值