Python中的诡异事:不可见字符!

文章目录

  • 前言
  • 1. 起因
  • 2. 调查
  • 3. 高能
  • 4. 释惑

前言

  今天分享一件很诡异的事情,我写代码的时候遇到了不可见的字符!!!

1. 起因

  今天在使用pipreqs导出项目中所依赖的库时突然报错了:

pipreqs . --encoding=utf-8 --force

# 以下是报错信息
ERROR: Failed on file: ./build.py
Traceback (most recent call last):
  File "/usr/local/bin/pipreqs", line 8, in <module>
    sys.exit(main())
  File "/usr/local/lib/python3.8/dist-packages/pipreqs/pipreqs.py", line 528, in main
    init(args)
  File "/usr/local/lib/python3.8/dist-packages/pipreqs/pipreqs.py", line 455, in init
    candidates = get_all_imports(input_path,
  File "/usr/local/lib/python3.8/dist-packages/pipreqs/pipreqs.py", line 131, in get_all_imports
    raise exc
  File "/usr/local/lib/python3.8/dist-packages/pipreqs/pipreqs.py", line 117, in get_all_imports
    tree = ast.parse(contents)
  File "/usr/lib/python3.8/ast.py", line 47, in parse
    return compile(source, filename, mode, flags,
  File "<unknown>", line 1
    # -*- coding:utf-8 -*-
    ^
SyntaxError: invalid character in identifier

  直接来了SyntaxError#竟然是个无效字符,字符#表示十分的无辜,当事人表示十分的震惊!!!这不是离天下之大谱,滑天下之大稽吗???这就一行代码注释,能够错到哪里去!

在这里插入图片描述

2. 调查

  头一次遇到这种邪门的事情,我就查看了一下pipreqs 源码,代码很简单,我就摘取了报错的部分:

# pipreqs/pipreqs.py line 112
for file_name in files:
    file_name = os.path.join(root, file_name)
    with open(file_name, "r", encoding=encoding) as f:
        contents = f.read()
    try:
        tree = ast.parse(contents)	# 在这里报错了
        for node in ast.walk(tree):
            if isinstance(node, ast.Import):
                for subnode in node.names:
                    raw_imports.add(subnode.name)
            elif isinstance(node, ast.ImportFrom):
                raw_imports.add(node.module)
    except Exception as exc:
    	...

  意思也很好理解,pipreqs读取当前工程下的所有python文件,然后使用ast库进行语法分析,获取python文件所依赖的库名。既然这部分报错了,我就直接拿了出来,此时,我高度怀疑ast存在重大bug

3. 高能

  为了确认ast在解析文件时存在bug,我对当前工程下的所有python文件进行一一测试,然而,事情的发展却超出了我的预料:第二个文件(process_data.py)竟然能够可以解析!
  我看了下这个文件,开头也是一样的注释,然而却没有报错。难道是编码有问题?我打开了Pycharm看了一下,也没有问题:

在这里插入图片描述
  这也太诡异了吧,然后我又debug了一下,看下文件的内容,确定也没有问题:

在这里插入图片描述
  想不通了,于是问了下ChatGPT

在这里插入图片描述
  给出了四个怀疑点,基本都是一一排除了,python 3.8、文件为utf-8编码,无语法错误,注释也没有什么问题。但有一个点却无法理解:不可见的特殊字符?
  不可见?既然是个字符,即使不可见也得有位置吧。于是乎,最诡异的事情来了:

在这里插入图片描述
  还真的有一个空字符,在第一个位置,这。。。空字符还能占个位置?
  打印了一下ASCII,发现其值竟然是65279,空字符竟然有ASCII值,顿时觉得这个问题不简单,难道还真的不可见?

在这里插入图片描述

4. 释惑

  百度了一下发现,ASCII值为65279是因为文件采用UTF-8 BOM编码导致的,这是Windows环境下创建文件时默认的编码方式,对此还专门看了一下,还真是:

在这里插入图片描述
  这在Pycharm中也有这项设置,默认情况下在Pycharm中创建新文件时会采用UTF-8 with NO BOM编码,也就是常说的UTF-8,而之所以ast库有的能够正常解析文件有的却不可以,是可能有的文件不是在Pycharm中创建的,导致了这种诡异的时间发生了。同时,我用二进制的方式读了一下文件,发现前三个字节是\xEF\xBB\xBF,这也正是UTF-8 BOM编码时自动添加的。

py_file = './build.py'
with open(py_file, 'r', encoding='utf-8') as f:
    contents = f.read()
    if ord(contents[0]) == 65279:
        print('UTF-8 BOM')

with open(py_file, 'rb') as f:
    contents = f.read(3)
    if contents == b'\xEF\xBB\xBF':
        print('UTF-8 BOM')

# UTF-8 BOM
# UTF-8 BOM

  于是将文件编码由UTF-8 BOM改为UTF-8,问题就解决了!

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/70495.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Spring项目整合过滤链模式~实战应用

代码下载 设计模式代码全部在gitee上,下载链接: https://gitee.com/xiaozheng2019/desgin_mode.git 日常写代码遇到的囧 1.新建一个类,不知道该放哪个包下 2.方法名称叫A,干得却是A+B+C几件事情,随时隐藏着惊喜 3.想复用一个方法,但是里面嵌套了多余的逻辑,只能自己拆出来…

百川智能发布首个530亿参数闭源大模型,今年追上GPT-3.5

4月官宣创业&#xff0c;6月15日发布第一款7B开源模型&#xff0c;7月11日发布第二款13B、130亿参数开源模型。 平均保持2个月一个版本发布速度&#xff0c;8月8日&#xff0c;百川智能发布了创业以来的首个530亿参数闭源大模型——Baichuan-53B&#xff08;以下简称“53B”&a…

Android Https

本质&#xff1a;在客户端和服务端使用非对称加密协商出一套对称密钥&#xff0c;每次发送数据前加密&#xff0c;收到后解密&#xff0c;达到加密传输 http ssl 在http之下增加了安全层&#xff0c;用于保障http的加密传输 HTTPS连接 TLS连接步骤 1.客户端发送 client h…

Ubuntu 20.04 安装 Stable Diffusionn

步骤 1&#xff1a;安装 wget、git、Python3 和 Python3虚拟环境&#xff08;如果已安装可忽略这步骤&#xff09; sudo apt install wget git python3 python3-venv步骤 2&#xff1a;克隆 SD 项目到本地 git clone https://github.com/AUTOMATIC1111/stable-diffusion-webu…

Could not resolve host: mirrorlist.centos.org; Unknown error解决方法

今天服务器安装完CentOS系统后&#xff0c;安装网络的时候&#xff0c;出现无法联网yum yum -y install net-tools 以上代码无法运行并报错&#xff0c;这里我要提醒大家&#xff0c;如果在初始安装的时候选中安装网络工具模块就不用在安装net-tools了&#xff0c;因为我选中…

C#在自动化领域的应用前景与潜力

人机界面&#xff08;HMI&#xff09;开发&#xff1a;使用C#开发人机界面软件&#xff0c;实现与自动化设备的交互和监控。C#的图形界面设计能力和丰富的控件库使得开发人员能够创建直观、易用的界面。 数据采集与处理&#xff1a;C#可以与各种传感器、设备进行数据通信和采集…

Elasticsearch之kibana相关命令

1.中文分词器相关命令 2.拼音分词器相关命令

资讯速递 | ArkUI-X 预览版已正式开源!

OpenHarmony项目群技术指导委员会&#xff08;以下简称“TSC”&#xff09;-跨平台应用开发框架TSG所孵化项目 —— ArkUI-X&#xff0c;近期已正式开源 &#xff0c;开发者基于一套主代码&#xff0c;就可以将在OpenHarmony上开发的精美、高性能应用同时运行在Android、iOS等其…

21 | 朝阳医院数据分析

朝阳医院2018年销售数据为例,目的是了解朝阳医院在2018年里的销售情况,通过对朝阳区医院的药品销售数据的分析,了解朝阳医院的患者的月均消费次数,月均消费金额、客单价以及消费趋势、需求量前几位的药品等。 import numpy as np from pandas import Series,DataFrame impo…

成功解决ubuntu-22.04的sudo apt-get update一直卡在【0% [Waiting for headers]】

成功解决ubuntu-22.04的sudo apt-get update一直卡在【0% [Waiting for headers]】 问题描述解决方案 问题描述 在下载安装包的时候一直卡在0% [Waiting for headers]&#xff0c;报错信息如下&#xff1a; Get:1 file:/var/cudnn-local-repo-ubuntu1804-8.5.0.96 InRelease […

C#随机法 双峰函数 求极值 避免落入局部最优解

避免落入局部最优解&#xff0c;只要让步长够长即可。 x1 resultX1 random1.NextDouble()*100; 如果后面不乘以100&#xff0c;则很大概率落入负数的最大值 Random random1 new Random(DateTime.Now.Millisecond);double x1 0, resultX10,max-999999,maxTemp0;for (int i …

开源语言模型的历史和重要性;Edge浏览器将推出Bing AI重写文本功能

&#x1f989; AI新闻 &#x1f680; 微软即将推出桌面版Microsoft Edge浏览器的Bing AI重写文本功能 摘要&#xff1a;微软最近在桌面版Microsoft Edge浏览器中引入了一个新功能&#xff0c;允许用户使用Bing AI重写文本。用户可以选择不同的语气、格式和长度&#xff0c;然…

✅最新!自然指数中国科研机构百强名单,出炉!

【SciencePub学术】8 月 9 日&#xff0c;自然指数官网发布了最新的中国科研机构百强名单。名单根据各大机构2022年在自然科学领域的论文贡献份额进行排名。 其中&#xff0c;中国科学院以2053.76的论文贡献份额&#xff0c;位列榜首&#xff1b;中国科学院大学和中国科学技术…

[保研/考研机试] KY80 进制转换 北京大学复试上机题 C++实现

题目链接&#xff1a; KY80 进制转换https://www.nowcoder.com/share/jump/437195121691735660774 描述 写出一个程序&#xff0c;接受一个十六进制的数值字符串&#xff0c;输出该数值的十进制字符串(注意可能存在的一个测试用例里的多组数据)。 输入描述&#xff1a; 输…

Fast SAM与YOLOV8检测模型一起使用实现实例分割

Fast SAM与YOLOV8检测模型一起使用 部分源代码在结尾处可获取 晓理紫 1 使用场景 实例分割数据集的获取要比检测数据的获取更加困难&#xff0c;在已有检测模型不想从新标注分割数据进行训练但是又想获取相关物体的mask信息以便从像素级别对物体进行操作&#xff0c;这时就可以…

模拟实现消息队列项目(系列5) -- 服务器模块(虚拟主机)

目录 前言 1. 创建VirtualHost 1.1 定义虚拟主机的相关属性 1.2 VirtualHost 构造方法 1.3 交换机和队列的创建和删除 1.3.1 交换机操作 1.3.2 队列操作 1.4 绑定的创建和删除 1.5 发送消息到指定的队列/交换机 2. 实现路由规则Router 2.1 checkBindingKey() 2.2 checkRoutin…

【软件测试】接口测试工具APIpost

说实话&#xff0c;了解APIpost是因为&#xff0c;我的所有接口相关的文章下&#xff0c;都有该APIpost水军的评论&#xff0c;无非就是APIpost是中文版的postman&#xff0c;有多么多么好用&#xff0c;虽然咱也还不是什么啥网红&#xff0c;但是不知会一声就乱在评论区打广告…

springboot项目问题

目录标题 问题后端1.[mybatis报错Parameter start not found. Available parameters are [1, 0, param1, param2]](https://www.cnblogs.com/josephcnblog/articles/7077244.html) 知识后端1. [Select 数据表的字段与实体类的属性值](https://www.cnblogs.com/yanguobin/p/1191…

【SpringBoot学习笔记】04. Thymeleaf模板引擎

模板引擎 templates下的只能通过Controller来跳转&#xff0c;templates前后端分离&#xff0c;需要模板引擎thymeleaf支持 模板引擎的作用就是我们来写一个页面模板&#xff0c;比如有些值呢&#xff0c;是动态的&#xff0c;我们写一些表达式。而这些值&#xff0c;从哪来呢…

【JavaWeb】MySQL基础操作

1 通用语法规则 SQL语句可以单行或者多行书写&#xff0c;以分号结尾SQL语句不区分大小写&#xff0c;关键字建议使用大写单行注释 --注释内容&#xff08;通用&#xff09; # 注释内容&#xff08;MySQL独有&#xff09;多行注释 /* 注释内容 */ 2 语句 数据库 -- 查…