pip UnicodeDecodeError: 'ascii' codec can`t decode byte 异常分析及解决

问题如图:


这是一个很多人都遇到过的问题,pip因为编码格式而报错。

一路追查,错误发生地是

file_path=os.path.join(temp_dir,filename) 

result_path= result_path + p_path

由错误信息可以得知,这是在os.path.join方法中 将两个path对象进行连接操作由于产生了解码问题导致的异常,由于我的系统用户名是中文,推测这是一个因为中文路径导致的问题。

'ascii' codec can`t decode byte 0xb2 这句话的意思是,ascii的编码方式不能解码一个0xb2字节,那么这个问题是怎么发生的呢?首先我们需要理解一下解码(decode)的概念,python2.7 中一个string对象存的其实是字节串,是最原始的数据。但要理解它的语义光有字节串还不够,我们还需要知道它的编码格式,就好像理解其他人说的话光有听觉还不行,必须还要懂他所说的语言。编码格式规定了自然语言中的文字和符号的字节形式,例如我们经常听说的ascii中规定了 'a'=97  'A'=65 '0'=48 等,而在我国的汉字编码格式GBK中汉字 '春'=B4BA '天'=CCEC。可以看到这两种编码方式采用的字节数是不一样的,而解码的意义就是将一个以某种方式编码的字节串转化为一种你需要的(能够理解的)格式,在计算机中这种工作由解编码器(codec)完成。我们现在来解释一下这个错误信息,ascii解码器不能解码字节0xb2,这是因为ascii只支持(0-127)这么多种字符,而0xb2换算成10进制是178,自然不能被接受成任何一种字符,解码器发现非本格式的字节出现就会报错。因此可以确认,temp_dir和filename中至少有一个在os.path.join函数中进行了decode操作,而且这个发生了decode操作的string对象采用了非ascii编码。由于我使用的是中文系统,其很大可能是一种支持中文的编码。

说到这里我们还不得不提一下Unicode的概念,这是一种收录了世界上常用的大部分语言中字符的码集,有unicode-16,unicode-8等几种形式,后面的数字表示存储一个字符需要多少位。这种码集就像是一个会说各国语言的人,他能担任一个翻译的角色。有了这个翻译,我们便可以为每种编码格式与unicode之间编写一对编码/解码器,而不是为每两种编码格式之间编写一对编码解码器,前者的工作量远比后者小(n<n2)。这种解决问题的思路非常像电话线或者网线的铺设,因为每个用户只有一对线连到中心,并且通过中心可以连接到任意一个其他用户。

在Python中,unicode格式是被原生支持的,对一个string对象调用其decode方法(并提供编码格式)就可以生成其unicode对象

str1='中文’
u_str1=str1.decode('gbk')
str2='abc'
u_str2=str2.decode('ascii')

其对应的操作是

str3=u_str1.encode('gbk') 
str4=u_str2.encode('ascii')
str5=u_str2.encode('gbk') #可行 gbk 支持ascii全部字符

但如果 令str6=u_str1.encode('ascii')则不可行,或者令u_str3=str1.decode('ascii')也不可行,因为ascii字库中找不到对应'中文'两个字的值,后者会报出 UnicodeDecodeError:ascii codec can`t decode byte xx。


以上是我自己的分析。

有关os.path.join报错的信息,经检索,在冷风一夜的博客中提到,os.path.join在接受一个string和一个unicode对象时,会将string以ascii解码。

解决:

file_path = os.path.join(unicode(temp_dir,'gbk'), filename).encode('gbk')

将问题代码替换即可



  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值