Python入门第10篇(编码)

目录

一、编码是什么?

二、Python中编码

1.读取文件引发的问题

2.其实是Windows的问题

3.试着改改问题

4.各种骚操作

5.终极解决

6.推荐方案

总结

Python系列文章目录


前言

编码存在于所有文件,比较常见的ASCII、utf8、gbk等。最常用的还是utf8编码。

在编码领域,也会涉及到代码文件,那么也会涉及编码问题,今天就这一问题进行介绍。

一、编码是什么?

编码就是特定字符的集合,是用于显示特点的字符。比如ASCII只能显示256个字符,utf8则可以表示各种符号多种语言的文字,具有更好的包容性。

二、Python中编码

1.读取文件引发的问题

一般读取文件内容,我们这么写代码就可以了

with open("./.env", "r",encoding="utf-8") as f:
    print(f.read())

如上代码,是直接读取环境变量文件,并且设置了编码为utf8,这里如果编码不匹配,就会报错:

UnicodeDecodeError: 'gbk' codec can't decode byte 0x95 in position 8: illegal multibyte sequence

因为读取文件内容的时候,有些中文在不同编码格式下编码信息是不一样的,就会导致报错。

由于一般用的都是utf8编码,那我们平时都用utf8编码,这种出错的情况也会很少。

但是随着Python开发接触的越来越多,你一定会用到很多其他的包,这个时候可能就会出意外了。比如某个包提供一个读取配置文件的方法,你感觉应该没问题,结果执行的时候就报错了,然后翻到包里的代码去看,结果,我的天,它咋不设置编码格式!!!

with open(str(template_file), "r") as f:
    template = f.read()

一开始我就直接把人家包的代码给改了,加了encoding参数,问题暂时是解决了,但是会后患无穷,包不得更新,一个更新又出问题了,你如果都忘了这事,那真是神不知鬼不觉的。 

2.其实是Windows的问题

经过一系列了解,原来这个问题主要出在Windows系统。自从Python3开始,Python的默认编码就是utf8了,这个在Linux、Mac系统下都没问题的。唯独在Windows下有问题,简单说在Windows下Python获取当前编码,还和操作系统编码、区域啥的有关系了

3.试着改改问题

读取文件其实是一个解码的过程,根据提示通过gbk无法解码某个字符,说明当前读取文件用的是gbk编码,但是gbk解码出错,说明读取的文件编码不是gbk,看了下文件编码确实不是gbk,而是utf8。为啥会这样,一会我们说。我们先看咋解决

结合如上分析,一个办法就是我们把文件编码也改为gbk,应该就可以了呗。改了果然可以。

就当我以为要大功告成的时候,突然想起来,Linux一直没这种编码问题的,于是决定用相同代码和相同的文件(修改编码为gbk)在Linux环境测试。

哇咔咔,果断报错。UnicodeDecodeError: 'utf-8' codec can't decode byte 0xb2 in position 0: invalid start byte

通过上面的分析经验,我们知道Linux默认是用的utf8解码,但是我们的文件却改为了gbk编码,那不报错才怪呢

看来,我这个改法是不行的,不能Windows改好了,结果Linux废了。

还得找路子


这里顺便说下Windows下为啥文件编码默认就是utf8,但是默认解码却是gbk。

文件是我们新建的,和Python本身是没关系的,而文件新建其实我们一般在开发环境下操作,比如我用的就是VSCode,这些开发工具其实默认编码已经设置为了utf8,这也就是为啥文件编码默认是utf8的原因。

而解码是要Python代码来实现,而默认解码同样是Python底层控制的,开发环境在python底层之上,是无法反向干预的。而默认解码在Windows下和操作系统编码、区域(或根据操作系统语言匹配一个编码,gbk就是我们国家的编码)相关的。


4.各种骚操作

问题没解决,只能各种问AI、问度娘了

1)设置PYTHONIOENCODING环境变量————————————没卵用

2)locale.setlocale(locale.LC_ALL, ".UTF-8")——————————没卵用

3)_locale._getdefaultlocale = (lambda *args: ['en_US', 'utf8'])——没卵用

default_encoding = locale.getpreferredencoding()
print("当前环境的默认编码是:", default_encoding)

如上代码可以查看当前环境的默认编码,但是经过如上设置,这个默认编码还是cp936,其实就是gbk,cp936是Windows操作系统内部编码叫法,可见很大概率和操作系统有关系

4)sys.setdefaultencoding('utf-8')——————————————没卵用,还报错

这玩意其实是Python2中才有的,Python3默认编码就是utf8,这玩意取消了,所以在搜索信息的时候还要明确是Python3

5)指定sys.flags.utf8_mode————————————————没卵用,还报错

sys.flags.utf8_mode是只读属性无法设置

5.终极解决

好奇会害死猫

好奇也会让我都不想去吃饭,不想出去遛弯,只为找到真理

终于找到两个个靠谱的

1)设置环境变量PYTHONUTF8=1

测试no problem。

2)重写open,从而给open加了encoding参数

original_open = __builtins__.open
def uopen(*args, **kwargs):
    if "b" not in (args[1] if len(args) >= 2 else kwargs.get("mode", "")):
        kwargs.setdefault("encoding", "UTF-8")
    return original_open(*args, **kwargs)
__builtins__.open = uopen 如上代码干啥用的,使用了python的哪些技术点

测试同样ok

附上参考链接:1. 命令行和环境 — Python 3.12.3 文档icon-default.png?t=N7T8https://docs.python.org/3/using/cmdline.html#envvar-PYTHONUTF8

3)命令行运行增加-X utf8参数

运行py命令:python xx.py,注意是在python和xx.py之间增加

完整命令:python -X utf8 xx.py

 测试可用,不过仅限于命令窗口,PyCharm中可以设置运行的时候增加这个脚本,不过我用的CSCode,参考链接:Python open 默认编码修改_python open utf8-CSDN博客icon-default.png?t=N7T8https://blog.csdn.net/linuxweiyh/article/details/124538216

6.推荐方案

如上5.终极解决,有几个方案可选,但是从通用性考虑,还是通过改环境变量的方式最省事。

其他办法要不不通用,要不需要修改的代码比较多,比如重写open,涉及问题的代码文件都得加这个代码。

改环境变量就没这个问题,反正Linux默认就是utf8,Windows和Linux、Mac统一了也没啥问题。

总结

通过一个小小的编码,引出一个Windows操作系统下Python编码的问题,网上相关资料很多,但是真正解决问题的资料却偏少,是不是多数Python开发用Linux、Mac操作系统。

不管如何,总算解决问题了。


Python系列文章目录

Python入门第01篇(Python安装与开发工具)-CSDN博客

Python入门第02篇(pip、字符串、方法、json、io操作)_python json pip-CSDN博客

Python入门第03篇(异常处理、dotenv)_load_dotenv()-CSDN博客

Python入门第04篇(sqlite数据库相关)_cmd中使用sqlite-CSDN博客

Python入门第05篇(爬虫相关)-CSDN博客

Python入门第06篇(FastApi、uvicorn)_fastapi uvicorn-CSDN博客

Python入门第09篇(conda虚拟环境)-CSDN博客

Flask开发webapi初步及过程问题探究_flask webapi-CSDN博客

Linux下docker运行python_linux docker运行python-CSDN博客

  • 24
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
嗨!很高兴回答你关于Python游戏脚本入门的问题。在Python中,多线程是一种并发处理的技术,它允许程序同时执行多个线程,从而提高程序的运行效率和响应能力。在游戏开发中,多线程可以用于处理游戏中的多个任务或实现并行计算。 要在Python中使用多线程,可以使用内置的`threading`模块。下面是一个简单的示例,演示如何在Python中创建和启动多个线程: ```python import threading def task(): # 这里是线程要执行的任务 print("Hello, I'm running in a thread!") # 创建线程对象 thread1 = threading.Thread(target=task) thread2 = threading.Thread(target=task) # 启动线程 thread1.start() thread2.start() ``` 在上面的示例中,我们首先定义了一个`task`函数,这是线程要执行的具体任务。然后,我们使用`threading.Thread`类创建了两个线程对象`thread1`和`thread2`,并将`task`函数作为参数传递给它们。最后,我们调用`start`方法来启动这两个线程。 多线程的执行是并发的,所以你可能会看到输出信息交替出现。在实际的游戏开发中,你可以利用多线程来处理不同的游戏逻辑、计算复杂的物理模拟或者处理网络通信等任务,从而提升游戏的性能和玩家体验。 但是需要注意的是,多线程编程需要注意线程之间的同步和资源竞争问题。在游戏开发中,你可能需要使用锁和同步原语来确保线程之间的安全操作。 希望这个简单的介绍对你有所帮助!如果你有任何其他问题,请随时提问。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值