Windows下使用pip安装python包是报错-UnicodeDecodeError: 'ascii' codec can't decode byte 0xcb in position 0

时间:2022-10-15 20:21:04

先交待下开发环境:

  操作系统:Windows 7

  Python版本:2.7.9

  Pip版本:6.1.1

  其他环境忽略

在windows下使用pip下载python包,出现如下错误

 

[plain] view plain copy 
  1. Collecting xxxxxx  
  2.   Exception:  
  3.   Traceback (most recent call last):  
  4.     File "D:\Python27\lib\site-packages\pip-6.0.8-py2.7.egg\pip\basecommand.py", line 232, in main  
  5.       status = self.run(options, args)  
  6.     File "D:\Python27\lib\site-packages\pip-6.0.8-py2.7.egg\pip\commands\install.py", line 339, in run  
  7.       requirement_set.prepare_files(finder)  
  8.     File "D:\Python27\lib\site-packages\pip-6.0.8-py2.7.egg\pip\req\req_set.py", line 333, in prepare_files  
  9.       upgrade=self.upgrade,  
  10.     File "D:\Python27\lib\site-packages\pip-6.0.8-py2.7.egg\pip\index.py", line 305, in find_requirement  
  11.       page = self._get_page(main_index_url, req)  
  12.     File "D:\Python27\lib\site-packages\pip-6.0.8-py2.7.egg\pip\index.py", line 783, in _get_page  
  13.       return HTMLPage.get_page(link, req, session=self.session)  
  14.     File "D:\Python27\lib\site-packages\pip-6.0.8-py2.7.egg\pip\index.py", line 872, in get_page  
  15.       "Cache-Control": "max-age=600",  
  16.     File "D:\Python27\lib\site-packages\pip-6.0.8-py2.7.egg\pip\_vendor\requests\sessions.py", line 473, in get  
  17.       return self.request('GET', url, **kwargs)  
  18.     File "D:\Python27\lib\site-packages\pip-6.0.8-py2.7.egg\pip\download.py", line 365, in request  
  19.       return super(PipSession, self).request(method, url, *args, **kwargs)  
  20.     File "D:\Python27\lib\site-packages\pip-6.0.8-py2.7.egg\pip\_vendor\requests\sessions.py", line 461, in request  
  21.       resp = self.send(prep, **send_kwargs)  
  22.     File "D:\Python27\lib\site-packages\pip-6.0.8-py2.7.egg\pip\_vendor\requests\sessions.py", line 610, in send  
  23.       r.content  
  24.     File "D:\Python27\lib\site-packages\pip-6.0.8-py2.7.egg\pip\_vendor\requests\models.py", line 730, in content  
  25.       self._content = bytes().join(self.iter_content(CONTENT_CHUNK_SIZE)) or bytes()  
  26.     File "D:\Python27\lib\site-packages\pip-6.0.8-py2.7.egg\pip\_vendor\requests\models.py", line 655, in generate  
  27.       for chunk in self.raw.stream(chunk_size, decode_content=True):  
  28.     File "D:\Python27\lib\site-packages\pip-6.0.8-py2.7.egg\pip\_vendor\requests\packages\urllib3\response.py", line 256, in stream  
  29.       data = self.read(amt=amt, decode_content=decode_content)  
  30.     File "D:\Python27\lib\site-packages\pip-6.0.8-py2.7.egg\pip\_vendor\requests\packages\urllib3\response.py", line 186, in read  
  31.       data = self._fp.read(amt)  
  32.     File "D:\Python27\lib\site-packages\pip-6.0.8-py2.7.egg\pip\_vendor\cachecontrol\filewrapper.py", line 54, in read  
  33.       self.__callback(self.__buf.getvalue())  
  34.     File "D:\Python27\lib\site-packages\pip-6.0.8-py2.7.egg\pip\_vendor\cachecontrol\controller.py", line 217, in cache_response  
  35.       self.serializer.dumps(request, response, body=body),  
  36.     File "D:\Python27\lib\site-packages\pip-6.0.8-py2.7.egg\pip\download.py", line 268, in set  
  37.       return super(SafeFileCache, self).set(*args, **kwargs)  
  38.     File "D:\Python27\lib\site-packages\pip-6.0.8-py2.7.egg\pip\_vendor\cachecontrol\caches\file_cache.py", line 83, in set  
  39.       with FileLock(name) as lock:  
  40.     File "D:\Python27\lib\site-packages\pip-6.0.8-py2.7.egg\pip\_vendor\lockfile\mkdirlockfile.py", line 18, in __init__  
  41.       LockBase.__init__(self, path, threaded, timeout)  
  42.     File "D:\Python27\lib\site-packages\pip-6.0.8-py2.7.egg\pip\_vendor\lockfile\__init__.py", line 189, in __init__  
  43.       hash(self.path)))  
  44.     File "D:\Python27\lib\ntpath.py", line 84, in join  
  45.       result_path = result_path + p_path  
  46.   UnicodeDecodeError: 'ascii' codec can't decode byte 0xcb in position 0: ordinal not in range(128)  

'UnicodeDecodeError'这个词已经暴露了这个问题是个编码问题

 

什么原因导致了这样的问题?在我的电脑上出现这个问题的原因是由于我的用户目录是中文的,pip在下载的时候调用了这样一行代码

[python] view plain copy 
  1. temp_dir = tempfile.mkdtemp('-unpack', 'pip-')  

pip把下载的临时文件存放在了用户临时文件中,这个目录一般是C:\Users\用户名\AppData\Local\Temp,目录名中有中文,显然ascii这种编码是不支持的

 

那问题要怎么解决呢?有两种方法解决:

1、把上面的temp_dir那段代码修改一个不包含中文的目录,修改这段代码的文件位置在D:\Python27\Lib\site-packages\pip-6.1.1-py2.7.egg\pip\download.py(位置由个人python安装目录决定)

2、修改编码为gbk,修改D:\Python27\Lib\ntpath.py(位置由个人python安装目录决定)文件中的def join(path, *paths)函数,在函数内第一行加入

[python] view plain copy 
  1. # Join two (or more) paths.  
  2. def join(path, *paths):  
  3.     """Join two or more pathname components, inserting "\\" as needed."""  
  4.     reload(sys)  
  5.     sys.setdefaultencoding('gbk')  
  6.     result_drive, result_path = splitdrive(path)  
  7.     for p in paths:  
  8.         p_drive, p_path = splitdrive(p)  
  9.         if p_path and p_path[0] in '\\/':  
  10.             # Second path is absolute  
  11.             if p_drive or not result_drive:  
  12.                 result_drive = p_drive  
  13.             result_path = p_path  
  14.             continue  
  15.         elif p_drive and p_drive != result_drive:  
  16.             if p_drive.lower() != result_drive.lower():  
  17.                 # Different drives => ignore the first path entirely  
  18.                 result_drive = p_drive  
  19.                 result_path = p_path  
  20.                 continue  
  21.             # Same drive in different case  
  22.             result_drive = p_drive  
  23.         # Second path is relative to the first  
  24.         if result_path and result_path[-1] not in '\\/':  
  25.             result_path = result_path + '\\'  
  26.         result_path = result_path + p_path  
  27.     ## add separator between UNC and non-absolute path  
  28.     if (result_path and result_path[0] not in '\\/' and  
  29.         result_drive and result_drive[-1:] != ':'):  
  30.         return result_drive + sep + result_path  
  31.     return result_drive + result_path  

注意:

[python] view plain copy 
  1. reload(sys)  
  2. sys.setdefaultencoding('gbk')  

这两行代码是我后加入的

 

 

一切准备就绪,重新执行pip安装试试吧

 

总结:

1、据说python3的默认编码为'utf-8',可能不存在这种问题,没有实际测试

2、这次我直接修改了python和pip中的源码,体现了python是脚本语言的特性