jupyter UnicodeDecodeError 解决
报错如下:
C:\Users\Tung>jupyter notebook
[I 16:00:00.384 NotebookApp] JupyterLab extension loaded from c:\users\tung\appdata\local\programs\python\python37\lib\site-packages\jupyterlab
[I 16:00:00.384 NotebookApp] JupyterLab application directory is c:\users\tung\appdata\local\programs\python\python37\share\jupyter\lab
[I 16:00:00.387 NotebookApp] Serving notebooks from local directory: C:\Users\Tung
[I 16:00:00.387 NotebookApp] The Jupyter Notebook is running at:
[I 16:00:00.387 NotebookApp] http://localhost:8888/?token=a8709f161e8fb84523438b46a79232141312cbe122d43163
[I 16:00:00.388 NotebookApp] or http://127.0.0.1:8888/?token=a8709f161e8fb84523438b46a79232141312cbe122d43163
[I 16:00:00.388 NotebookApp] Use Control-C to stop this server and shut down all kernels (twice to skip confirmation).
Traceback (most recent call last):
File "c:\users\tung\appdata\local\programs\python\python37\lib\runpy.py", line 193, in _run_module_as_main
"__main__", mod_spec)
File "c:\users\tung\appdata\local\programs\python\python37\lib\runpy.py", line 85, in _run_code
exec(code, run_globals)
File "C:\Users\Tung\AppData\Roaming\Python\Python37\Scripts\jupyter-notebook.EXE\__main__.py", line 9, in <module>
File "C:\Users\Tung\AppData\Roaming\Python\Python37\site-packages\jupyter_core\application.py", line 270, in launch_instance
return super(JupyterApp, cls).launch_instance(argv=argv, **kwargs)
File "C:\Users\Tung\AppData\Roaming\Python\Python37\site-packages\traitlets\config\application.py", line 664, in launch_instance
app.start()
File "C:\Users\Tung\AppData\Roaming\Python\Python37\site-packages\notebook\notebookapp.py", line 1933, in start
self.write_browser_open_file()
File "C:\Users\Tung\AppData\Roaming\Python\Python37\site-packages\notebook\notebookapp.py", line 1843, in write_browser_open_file
self._write_browser_open_file(open_url, f)
File "C:\Users\Tung\AppData\Roaming\Python\Python37\site-packages\notebook\notebookapp.py", line 1851, in _write_browser_open_file
template = jinja2_env.get_template('browser-open.html')
File "C:\Users\Tung\AppData\Roaming\Python\Python37\site-packages\jinja2\environment.py", line 883, in get_template
return self._load_template(name, self.make_globals(globals))
File "C:\Users\Tung\AppData\Roaming\Python\Python37\site-packages\jinja2\environment.py", line 857, in _load_template
template = self.loader.load(self, name, globals)
File "C:\Users\Tung\AppData\Roaming\Python\Python37\site-packages\jinja2\loaders.py", line 115, in load
source, filename, uptodate = self.get_source(environment, name)
File "C:\Users\Tung\AppData\Roaming\Python\Python37\site-packages\jinja2\loaders.py", line 184, in get_source
contents = f.read().decode('gbk')#(self.encoding)
UnicodeDecodeError: 'gbk' codec can't decode byte 0xf2 in position 217187: illegal multibyte sequence
解决思路:
- 首先,报错文件为 ~~~Python\Python37\site-packages\jinja2\loaders.py 中 line184,
- 也就是在def get_source(self, environment, template)中,
- 打开发现 contents = f.read().decode('gbk'),(注:此处的‘gdk’我之前改过,你们的可能不一样)
- 问题应该出在变量f 上,而代码中 f = open_if_exists(filename) ,
- open_if_exists 是 from .utils import open_if_exists
- 打开 ~~~Python\Python37\site-packages\jinja2\utils.py 中的 open_if_exists 函数
- 发现 最后一行为 open(filename, mode) 问题就出在这
随后有国外热心网友的回复如下问题:
UnicodeDecodeError: 'utf8' codec can't decode byte 0xf4 in position 13: invalid continuation byte
解答:(文中链接:http://docs.python.org/2/library/codecs.html#codec-base-classes)
操作:
- 首先修改utils.py 中的 open_if_exists 函数
def open_if_exists(filename, mode="rb"):
"""Returns a file descriptor for the filename if that file exists,
otherwise ``None``.
"""
if not os.path.isfile(filename):
return None
#修改这里
import codecs
return codecs.open(filename, mode,encoding='utf-8', errors='replace')
- 然后修改 loaders.py 中 get_source 函数
def get_source(self, environment, template):
pieces = split_template_path(template)
for searchpath in self.searchpath:
filename = path.join(searchpath, *pieces)
f = open_if_exists(filename)
if f is None:
continue
try:
#修改这里
contents = f.read()
finally:
f.close()
mtime = path.getmtime(filename)
def uptodate():
try:
return path.getmtime(filename) == mtime
except OSError:
return False
return contents, filename, uptodate
raise TemplateNotFound(template)
总结
其实这就是一个编码不正确的问题,而且不易重现,即使你找到了一个大神,他将环境配置的跟你一模一样,这种问题也很难重现,就如同另一位网友的回答:
这种问题,过于特殊,因为没法进行测试,更谈不上解决。