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

news2024/11/23 20:08:29

文章目录

  • 前言
  • 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,问题就解决了!

在这里插入图片描述

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

AtcoderABC222场

A - Four DigitsA - Four Digits 题目大意 给定一个整数N&#xff0c;其范围在0到9999之间&#xff08;包含边界&#xff09;。在将N转换为四位数的字符串后&#xff0c;输出它。如果N的位数不足四位&#xff0c;则在前面添加必要数量的零。 思路分析 可以使用输出流的格式设…

Petrel解释二维浅地层数据

Petrel是斯伦贝谢开发的一款地质解释和建模软件&#xff0c;有点像地理信息系统的ArcGIS&#xff0c;主要用于数据分析和展示。它不是用来处理原始数据的&#xff0c;而是集成各种处理后的结果数据进行特征分析和目标拾取。当然&#xff0c;它也能读取原始数据&#xff0c;比如…

安装程序指南:FMSoft_uniGUI_Complete_Professional1.9.1567

解压和安装程序指南&#xff1a;FMSoft_uniGUI_Complete_Professional https://t00y.com/dir/1041485-3049764-93c76d?56118062 引言&#xff1a; 在开发软件的过程中&#xff0c;我们经常需要安装各种工具和框架来帮助我们实现项目的目标。本文将为您提供一个详细的指南&…

怎么入驻抖音的产业带服务商呢?

作为互联网行业中的明星企业之一&#xff0c;抖音电商近年来一直备受市场瞩目&#xff0c;甚至于某种角度而言&#xff0c;围绕抖音电商的研究和解读已成为一门“显学”。 如果说2021年之前&#xff0c;抖音试水电商业务的方式大多以主播、品牌及商家申请找cmxyci自发摸索为主…

漫谈拥塞控制: a Decade of Wasted Bandwidth?

梭子蟹终于上市了&#xff0c;早早起来准备去买来尝鲜&#xff0c;出发之前想起大概 2016&#xff0c;2017 年左右温州老板推荐给我的一篇好论文&#xff1a;The Linux Scheduler: a Decade of Wasted Cores&#xff0c;但有点长&#xff0c;就读个梗概&#xff1a;a Decade of…

中科亿海微ROM使用

标题 ROM&#xff08;Read-Only Memory&#xff0c;只读存储器&#xff09;是一种在FPGA&#xff08;Field-Programmable Gate Array&#xff0c;现场可编程门阵列&#xff09;中常用的存储器类型。与RAM&#xff08;Random Access Memory&#xff0c;机存取存储器&#xff09;…

用HTML+JavaScript构建C++类(Class)代码转换为MASM32代码的平台

一、需求分析 在使用MASM32编写Windows应用程序时&#xff0c;经常要调用Windows API接口函数 和 相应的数据结构&#xff0c;这些数据结构中有很多是类&#xff08;Class&#xff09;&#xff0c;对于那些在MASM32没有定义的类&#xff0c;我们需要自己来转换。比如&#xff…

Mybatis 初识

目录 1. MyBatis入门 1.1 MyBatis的定义 1.2 MyBatis的核心 MyBatis的核心 JDBC 的操作回顾 1.3 MyBatis的执行流程 MyBatis基本工作原理 2. MyBatis的使用 2.1 MyBatis环境搭建 2.1.1 创建数据库和表 2.1.2 添加MyBatis框架支持 老项目添加MyBatis 新项目添加MyBatis 2.1.3 设…

第一份工作要怎么找呀

前言&#xff1a;相信看到这篇文章的小伙伴都或多或少有一些编程基础&#xff0c;懂得一些linux的基本命令了吧&#xff0c;本篇文章将带领大家服务器如何部署一个使用django框架开发的一个网站进行云服务器端的部署。 文章使用到的的工具 Python&#xff1a;一种编程语言&…

LeetCode150道面试经典题--赎金信(简单)

1.题目 给你两个字符串&#xff1a;ransomNote 和 magazine &#xff0c;判断 ransomNote 能不能由 magazine 里面的字符构成。 如果可以&#xff0c;返回 true &#xff1b;否则返回 false 。 magazine 中的每个字符只能在 ransomNote 中使用一次。 2.示例 3.思路 统计字…

JVM 中一次完整的 GC 流程和对象如何晋升到老年代?

前言 今天来分享一道比较好的面试题&#xff0c;JVM 中一次完整的 GC 流程是怎样的以及对象如何晋升到老年代&#xff1f;对于这个问题&#xff0c;我们一起看看考察点和比较好的回答吧。 考察点 Java 虚拟机能够替我们回收内存空间&#xff0c;清除垃圾对象&#xff0c;因此…

《嵌入式 - 嵌入式大杂烩》SVC和PendSV异常详解

1 操作模式 在讨论PendSV和SVC异常前,需要先了解Cortex-M的模式和两个特权等级。 Figure 1 1 操作模式和特权等级 两种模式为handler模式和线程(thread)模式,这两种模式是为了区别正在执行代码的类型;handler模式为异常处理例程的代码;线程模式为普通应用程序的代码。 两…

【云原生】Kubernetes 概述

Kubernetes 概述 1.Kubernetes 简介 Kubernetes 是一个可移植的、可扩展的、用于管理容器化工作负载和服务的开源平台&#xff0c;它简化&#xff08;促进&#xff09;了声明式配置和自动化。它有一个庞大的、快速增长的生态系统。Kubernetes 的服务、支持和工具随处可见。 K…

计算机视觉中的Transformer

几十年来&#xff0c;理论物理学家一直在努力提出一个宏大的统一理论。通过统一&#xff0c;指的是将被认为是完全不同的两个或多个想法结合起来&#xff0c;将它们的不同方面证明为同一基础现象。一个例子是在19世纪之前&#xff0c;电和磁被看作是无关的现象&#xff0c;但电…

HCIP-linux和kvm

1、linux linux安装教程参考&#xff0c;https://blog.51cto.com/cloudcs/5245337 yum源配置 本地yum源配置&#xff1a; 8版本配置&#xff1a;将光盘iso挂载到某个目录&#xff0c;/dev/cdrom是/dev/sr0软链接&#xff0c;# mount /dev/cdrom /mnt&#xff0c;# ls /mnt Ap…

项目知识点记录

1.使用druid连接池 使用properties配置文件&#xff1a; driverClassName com.mysql.cj.jdbc.Driver url jdbc:mysql://localhost:3306/book?useSSLtrue&setUnicodetrue&charsetEncodingUTF-8&serverTimezoneGMT%2B8 username root password 123456 #初始化链接数…

Python-OpenCV中的图像处理-霍夫变换

Python-OpenCV中的图像处理-霍夫变换 霍夫变换霍夫直线变换霍夫圆环变换 霍夫变换 霍夫(Hough)变换在检测各种形状的技术中非常流行&#xff0c;如果要检测的形状可以用数学表达式描述&#xff0c;就可以是使用霍夫变换检测它。即使要检测的形状存在一点破坏或者扭曲也是可以使…

《人月神话》:我所遇见的“焦油坑”

最近在读《人月神话》这本书。 发现大部分task延期和研发关系不是很大&#xff0c;技术为业务服务&#xff0c;但是偿还不了业务债。 焦油坑的概念源自于挖掘坑井时的一种不幸状况。当挖掘坑井时&#xff0c;首先会进入表土层&#xff0c;进展颇快。但接下来遇到了沥青或泥浆…

Highcharts引入

Highcharts是和jQuery一起使用的&#xff0c;所以需要下载好jQuery jQuery下载方式&#xff1a;访问&#xff1a;http://cdn.staticfile.org/jquery/2.1.4/jquery.min.js&#xff0c;然后全选复制到自己新建的txt文档中&#xff0c;最后把扩展名改为js。 Highcharts下载方式&…

红帽8.5 ansible 安装和部署 |(简单版)

安装 配置yum仓库&#xff1a; vim /etc/yun.repo.d/aliyun.repo [AppStream] nameApp baseurlhttps://mirrors.aliyun.com/centos/8-stream/AppStream/x86_64/os gpgcheck0[BaseOS] namebase baseurlhttps://mirrors.aliyun.com/centos/8-stream/BaseOS/x86_64/os gpgcheck…