微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

PyExecJs 运行含有中文的JavaScript文件时,出现编码错误的解决方案

本文目录

问题分析

​ 在 Python 中使用 PyExecJS 库运行 JavaScript 代码文件时,若文件中含有中文字符,则会被抛出一个文件编码异常 UnicodeEncodeError: 'gbk' codec can't encode character '\ufeff' in position 61: illegal multibyte sequence

异常详情如下:

Traceback (most recent call last):
  File "D:/Projects/PythonProjects/ConfigurationTabLeverificationTools/checkoutAllRoomFishCanKill.py", line 233, in <module>
    game_table = execjs.get('local_node').compile(js_code).eval('_default')
  File "D:\Projects\PythonProjects\ConfigurationTabLeverificationTools\venv\lib\site-packages\execjs\_abstract_runtime_context.py", line 27, in eval
    return self._eval(source)
  File "D:\Projects\PythonProjects\ConfigurationTabLeverificationTools\venv\lib\site-packages\execjs\_external_runtime.py", line 77, in _eval
    return self.exec_(code)
  File "D:\Projects\PythonProjects\ConfigurationTabLeverificationTools\venv\lib\site-packages\execjs\_abstract_runtime_context.py", line 18, in exec_
    return self._exec_(source)
  File "D:\Projects\PythonProjects\ConfigurationTabLeverificationTools\venv\lib\site-packages\execjs\_external_runtime.py", line 86, in _exec_
    output = self._exec_with_pipe(source)
  File "D:\Projects\PythonProjects\ConfigurationTabLeverificationTools\venv\lib\site-packages\execjs\_external_runtime.py", line 102, in _exec_with_pipe
    stdoutdata, stderrdata = p.communicate(input=input)
  File "C:\Program Files\python38\lib\subprocess.py", line 1028, in communicate
    stdout, stderr = self._communicate(input, endtime, timeout)
  File "C:\Program Files\python38\lib\subprocess.py", line 1393, in _communicate
    self._stdin_write(input)
  File "C:\Program Files\python38\lib\subprocess.py", line 962, in _stdin_write
    self.stdin.write(input)
UnicodeEncodeError: 'gbk' codec can't encode character '\ufeff' in position 61: illegal multibyte sequence

解决方

​ 网络上其他文章解决方案大多是直接修改 Python 标准库中 subprocess.py 模块中代码的方式,将其中编码格式设定为 UTF-8

​ 但我认为,不到万不得已,能够在不修改官方标准模块文件,不对非项目代码文件进行侵入式的修改,就能够将问题解决解决方案,才是更值得推荐的做法。

​ 通过尝试,发现借助 Python 高度动态化的特性,在代码运行过程中,对 subprocess.py 模块中的 Popen 类进行重置及可解决该问题。具体代码如下。

import subprocess

# 创建一个新的 Popen 类,并继承自 subprocess.Popen
class MySubprocesspopen(subprocess.Popen):
    def __init__(self, *args, **kwargs):
        # 在调用父类(即 subprocess.Popen)的构造方法时,将 encoding 参数直接置为 UTF-8 编码格式
        super().__init__(encoding='UTF-8', *args, **kwargs)


# 必须要在导入 PyExecJS 模块前,就将 subprocess.Popen 类重置为新的类
subprocess.Popen = MySubprocesspopen

# 导入 PyExecJS 模块
import execjs

# 在后面继续写程序具体的执行逻辑 ...

原文地址:https://www.jb51.cc/wenti/3287485.html

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐