前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
社区首页 >专栏 >惊!\u202a错误,百分之九十都不知道的隐藏在文件路径里的惊天秘密!(干货收藏)

惊!\u202a错误,百分之九十都不知道的隐藏在文件路径里的惊天秘密!(干货收藏)

作者头像
灰小猿
发布于 2020-09-23 02:59:24
发布于 2020-09-23 02:59:24
6.6K00
代码可运行
举报
运行总次数:0
代码可运行

今天在做Python文件处理的时候遇到这样一个问题。

使用鼠标右键获取到文件路径并使用的时候发现总是发生错误,导致文件路径读取失败。

然后上网查了一下发现很多小伙伴都经历过类似的问题,网上的回答也有很多,但是大部分都是说在路径字符串前加r变成原始字符串、或者手动输入路径字符串进行解决。

以下是大灰狼按照网上已有一些方法进行的尝试:

尝试一:将复制到的路径前加上r成为原始字符串:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
#文件路径修改为原始字符串
import shutil
import os.path as op
path1 = r'D:\data\venv\test.txt'   #从文件夹直接复制而来的路径
path2 = r'D:\data\.idea'   #从文件夹直接复制而来的路径
shutil.copy(path1, path2)

如上面代码所示,在复制到的文件路径前加上r成为原始字符串之后,运行结果并没有任何变化,仍然是显示这样的错误:

尝试二:文件路径手动输入

之后大灰狼又将字符手动输入,并在字符串前方分别使用了r和没有使用r。

发现文件路径在手动输入的情况下,即使不将路径变为原始字符串,程序仍然可以运行:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
#文件路径手动输入
import shutil
import os.path as op
path1 = r'D:\data\venv\test.txt'   #手写的路径
path2 = r'D:\data\.idea'   #手写的路径
shutil.copy(path1, path2)

运行结果:

但是将前后两个代码细心对比的小伙伴就会发现。

除了文件路径一个是复制过来的、一个是手动输入的以外,在代码上并没有任何区别,但是就是这样的两个代码,手动输入的可以运行,而复制过来的路径无法运行。

这就很是疑惑了,明明是看上去一模一样的两个代码,为什么运行之后会有这样的差别呢?

尝试三:文件路径分割

于是我将复制而来的文件路径进行了分割对比,这一对比,那可坏了!

代码是这样的:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
#文件路径分割
import shutil
import os.path as op
path1 = r'D:\data\venv\test.txt'   #从文件夹直接复制而来的路径
path2 = r'D:\data\.idea'   #从文件夹直接复制而来的路径
print(path1.split('\\'))
print(path2)
shutil.copy(path1, path2)

我将复制过来的两个路径字符串,第一个以反斜杠将其分割成列表形式,而第二个不做任何处理直接输出,发现运行结果是这样的:

未做处理的路径在输出出来以后并没有发现什么异常,但是经过反斜杠分割处理后的路径就不一样了。在文件路径的的最前方竟然出现了\u202a!

当时的我也是十分的懵逼…

从代码中可以看到,我们的文件路径的字符串中并未有\u202a,而在经过分割之后的列表中竟然出现了\u202a,但是第二个同样也是复制过来的路径,未处理直接输出,却没有\u202a的字符串出现。

此时此刻的大灰狼也是吓出了一身冷汗…难道这就是传说中神秘的\u202a字符嘛?

真相大白!

带着对\u202a百思不得其解的好奇,我踏上了询问度娘的漫漫征程。

好家伙,不查不知道,一查吓一跳!

\u202a这个字符其实一直都存在,只不过是我们凡人的肉眼还没有齐天大圣般程序猿的法力,单凭借简单的输出并不能让这个字符显出原形。

但不可否认的是,在我们右击文件复制其路径的时候,\u202a这个字符就已经存在我们的剪切板上了,但是在我们粘贴的时候它并不会让我们看见。

更神奇的是,这个字符并不是我们每次右击复制文件路径时都会出现。

它只会在我们从右向左复制的时候出现\u202a,而从左向右复制的时候并不会出现这个字符。

嗯…还有这神操作…

看到这里,相比我们这等凡人对于\u202a的神秘之处也略知一二了吧。

没错,我们平常读取文件路径的时候,都是从左向右读取的,依次是:某一个盘/文件夹/文件,并不是文件/文件夹/某一个盘这样。

但是在我们右击文件复制路径的时候,难免会从左或从右开始复制,所以在计算机上,为了对于那些从右至左复制而来的路径,在读取的时候可以从左向右读取,就会在文件路径前隐式的加上\u202a,表示路径是从左向右读取的。

所以这个符号应该是windows在做文件名显示的时候,为了保证文件路径是从左往右显示所加的强制字符。

现在了解了\u202a存在的原因,接下来就是在我们复制文件路径之后并在程序中使用它的时候,如何去掉这个看不见的字符串,

尝试四:normpath()函数处理路径

大灰狼在网上也有看到说使用os.path包的normpath()函数可以解决。

在这里说明一下normpath()函数的作用:将路径正规化:去除多余的分隔符,将 . 和 … 变成真实路径,处理错误的斜杠。

听着好像是有点用哈,于是大灰狼带着满心的疑惑使用normpath()函数尝试了一下,万一可以呢不是。

并且为了更加直观的看到normpath()函数是否可以将文件路径正规化,大灰狼将同样将经过normpath()函数处理后的两个文件路径分割和不分割处理,代码如下:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
#normpath()函数处理
import shutil
import os.path as op
path1 = op.normpath(r'D:\data\venv\test.txt')   #从文件夹直接复制而来的路径
path2 = op.normpath(r'D:\data\.idea')   #从文件夹直接复制而来的路径
print(path1.split('\\')) #将路径1以反斜杠分隔为列表输出
print(path2)
shutil.copy(path1, path2)

结果可想而知,normpath()函数并没有对文件路径做出改变,在进行分割时候输出的结果上还是存在\u202a。

这下可好了,尝试了网上的很多方法,还是无法解决这个\u202a的文件路径问题。

但是对于我这样一个连写代码都不想多敲一下键盘的程序猿来说,怎么可能一次次的手动输入文件路径,或者一次次的修改路径呢,于是就有了这样的神奇操作…

定义函数处理问题

没错!为了更好的偷懒,我写了这样一个处理函数,该函数接收的变量是一个文件路径,也就是我们从文件属性中复制过来的文件路径,经过该函数的处理之后,可以重新返回一个可以被程序使用的没有\u202a的正规路径。

并且是使用正斜杠连接,不会出现因为反斜杠而导致的转义字符错误。

我的代码实现效果如下:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
#函数处理
import shutil
import os.path as op
path1 = 'D:\dmp\path\Test.txt'   #从文件夹直接复制而来的路径
path2 = 'D:\dmp\deposit'   #从文件夹直接复制而来的路径

'''将负责路径而来的路径标准化'''
def path_normal(path):
    path = path.split('\\')
    path[0] = path[0][-2: len(path[0])]
    path = '/'.join(path)
    return path

print('转换前:' + path1)
print('分割成列表:')
print(path1.split('\\'))
path1 = path_normal(path1)      #调用函数进行路径转换
print('转换后:' + path1)
print('分割成列表:')
print(path1.split('/'))
path2 = path_normal(path2)
shutil.copy(path1, path2)   #复制文件和文件夹

运行结果:

可以看出,经过这个函数处理后的文件路径再次以斜杠分割以后,并没有出现\u202a的字符串,并且在直接运用到文件处理的函数时没有报错。

函数比较简单,只有四行代码便将在文件路径前看不到\u202a分离出来了,比较实用。

函数的使用方法是传入需要处理的文件路径,并将处理后的正规路径返回出来,只需要接收就可以使用了。

路径标准化处理函数

以下是该函数的代码:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
#路径标准化处理
'''将负责路径而来的路径标准化'''
def path_normal(path):
    path = path.split('\\')
    path[0] = path[0][-2: len(path[0])]
    path = '/'.join(path)
    return path

现在,你应该对于复制文件路径报错的原因和处理方法有了简单的了解了吧,虽然比较简单,但也的确是很多程序中比较常见和容易忽略的错误。收藏起来以备后用!

觉得不错记得点赞关注喔, 同时你也可以关注我的微信公众号“灰狼洞主”获取更多好玩的Python项目分享和互联网资讯! 大灰狼期待与你一同进步!

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2020/05/04 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
python 文件和路径操作函数小结
1: os.listdir(path) //path为目录  功能相当于在path目录下执行dir命令,返回为list类型  print os.listdir('..')  2: os.path.walk(path,visit,arg)  path :是将要遍历的目录  visit :是一个函数指针,函数圆形为:  callback(arg,dir,fileList)  其中arg为为传给walk的arg , dir是path下的一个目录,fileList为dir下的文件和目录组成的list, arg:传给visit用的  3:os.path.split(path)  path 为一个路径,  输出,把path分成两部分,具体看实例:  print os.path.split("abc/de.txt")  ('abc', 'de.txt')  os.path.split("abc")  (", 'abc')  print os.path.split("de/abc/de")  ('de/abc', 'de')  4: os.path.splitext(filename)  把文件名分成文件名称和扩展名  os.path.splitext(abc/abcd.txt)  ('abc/abcd', '.txt')  5: os.path.dirname(path)  把目录名提出来  print os.path.dirname("abc")  #输出为空  print os.path.dirname('abc\def')  abc  6: os.path.basename(filename)  取得主文件名  print os.path.basename('abc')  abc  print os.path.basename('abc.txt')  abc  print os.path.basename('bcd/abc')  abc #这个需要注意不包括目录名称  print os.path.basename('.')  .  7:os.mkdir(path, [mode])  path为目录名: 这里有个要求,只能创建一级目录  比如path为 abc/def 则当前目录下必须存在abc 否则失败  8: os.makedirs(path [,mode])  可以创建多级目录  9:os.remove(path)删除一个文件,一定是一个文件  os.removedirs(path) 删除一个目录下所有东西  os.rmdir(path) 删除一个目录,而且一定要空,否则os.errer  10:os.walk(path)  遍历path,返回一个对象,他的每个部分都是一个三元组  ('目录x',[目录x下的目录list],目录x下面的文件)  举例:  a = os.walk('.')  for i in a:  print i  11:shutil.copy(src,dst)  把文件src内容拷贝到文件dst中。,目标区域必须可以写,如果dst存在,则dst被覆盖  ――――――――――――――――――  11.1 os.path -- 普通的路径名操作  这个模块实现一些在路径名称上有用的函数。  警告:在 Windows 上,这些函数中的多个不能正确地支持 UNC 路径名。splitunc() 和 ismount() 可以正确地处理它们。  abspath(path)  返回 path 路径名一个规格化的绝对化的版本。在大多数平台上,相当于normpath(join(os.getcwd(), path))。1.5.2版本中的新特性。  basename(path)  返回 path 路径名最底部的名称。这是由 split(path)返回的对的第二半部分。注意这个函数的结果不同于Unix basename 程序;UNIX的 basename对于'/foo/bar/' 返回 'bar',basename() 函数返回一个空字符串('')。  commonprefix(list)  返回最长的路径前缀(采取字符的字符),是 list中所有路径的一个前缀。如果 list 为空,返回空字符串('')。注意可以返回无效的路径因为它每次操作一个字符。  dirname(path)  返回 path 路径名的目录名称。这是由 split(path)返回的对的第一半部分。  exists(path)  如果 path 与一个已存在的路径关联返回True。对于损坏的符号连接返回 False 。在一些平台上,如果权限没有被授予在请求的文件上执行os.stat()这个函数可能返回False,即使该 path 实际上存在。  lexists(path)  如果 path 与一个已存在的路径关联返回 True 。对于损坏的连接返回 True
py3study
2020/01/09
1.8K0
【Python】文件的选择性压缩和全压缩,一般人不告诉的实用小技巧!
最近Python在各大社交媒体被炒得那是一个如火如荼呀,很多大灰狼几个其他领域的朋友都过来问我关于Python的学习,尤其是在自动化办公领域的用途。
灰小猿
2020/09/23
9180
深度对比Python中4大文件处理库(os、shutil、glob、pathlib)
os库应该是使用频率最高的一个文件处理库,但是不得不说Python中还有几个其它的文件处理库,像shutil库、glob库、pathlib库,它们可以说是相互补充,有着自己好用的方法。黄同学亲切的将它们合称为Python文件处理库的四大天王。
快学Python
2021/12/07
7.7K0
深度对比Python中4大文件处理库(os、shutil、glob、pathlib)
os.path:Python操作和处理文件路径
os.path是平台独立的文件名管理库,使用该库能够很方便来处理多个平台上的文件。即使程序不打算在平台之间移值,也应当使用os.path库来完成可靠的文件名解析。
luckpunk
2023/09/27
5010
os.path:Python操作和处理文件路径
Python当前文件路径与文件夹删除操作
  Python的文件操作跟Java存在部分差异。由于项目需要,近期使用python进行模块开发时遇到一些常见的文件操作便上网搜罗了一番,感觉众说纷纭。因此,结合自身的使用场景,贴一段python代码供后续查阅。
云海谷天
2022/08/09
1.4K0
Python当前文件路径与文件夹删除操作
python os.path模块
语法:  os.path.join(path1[,path2[,......]])
py3study
2020/01/07
9170
Python文件与目录-os模块和shutil模块详解
os模块和 shutil模块是Python处理文件/目录的主要方式。os模块提供了一种使用操作系统相关功能的便捷方式,shutil模块是一种高级的文件/目录操作工具。
唔仄lo咚锵
2021/09/14
6540
Python文件与目录-os模块和shutil模块详解
Python文件路径解谜:深入剖析os.path系列函数的精髓
在Python中,os.path模块提供了一系列用于处理文件路径和文件系统的函数。它是Python标准库中os模块的一部分。本文将深入探讨os.path系列函数的使用方法,从入门到精通。
子午Python
2023/08/13
4730
偷学Python二十六|OS.path模块的详细使用说明
大家好,从本周起早起Python将持续更新由小甜同学从初学者的角度学习Python的笔记,其特点就是全文大多由新手易理解的代码与注释及动态演示。刚入门的读者千万不要错过!
刘早起
2020/06/04
8780
python 基本模块
1.os模块  os模块包装了不同操作系统的通用接口,使用户在不同操作系统下,可以使用相同的函数接口,返回相同结构的结果。  os.name:返回当前操作系统名称('posix', 'nt', 'os2', 'mac', 'ce' or 'riscos')  os中定义了一组文件、路径在不同操作系统中的表现形式参数,如    os.sep(文件夹分隔符,windows中是 \ )    os.extsep(扩展名分隔符,windows中是 . )    os.pathsep(目录分隔符,windows中是 ; )    os.linesep(换行分隔符,windows中是 \r\n )  os中有大量文件、路径操作的相关函数,如:    listdir(path):列举目录下的所有文件    makedir(path):创建文件夹,注:创建已存在的文件夹将异常    makedirs(path):递归式的创建文件夹,注:创建已存在的文件夹将异常    remove(filename):删除一个文件    rmdir(path):删除一个文件夹,注:删除非空的文件夹将异常    removedirs(path):递归的删除文件夹,直到有一级的文件夹非空,注:文件夹路径不能以'\'结束    rename(src,dst):给文件或文件夹改名(可以改路径,但是不能覆盖目标文件)    renames(src,dst):递归式的给文件或文件名改名    walk(path):列举path下的所有文件、文件夹  os中与进程相关的操作,如:    execl(path):运行一个程序来替代当前进程,会阻塞式运行    _exit(n):退出程序    startfile(filename):用与文件关联的程序运行,关联程序打开后,立即返回    system(cmd):运行一个程序或命令,会立即返回,并在cmd执行完成后,会返回cmd退出代码  os.path:在不同的操作系统中调用不同的模块,是一个可import的模块,这个模块中提供很多有用的操作:    abspath(path):返回path的绝对路径,若path已经是绝对路径了,则保持。    basename(path):返回path中的文件名。    commonprefix(list):返回list中的统一前缀,用于获得一组字符串的左起相同的内容    dirname(path):返回path中的文件夹部分,结果不包含'\'    exists(path):文件或文件夹是否存在    getatime(path):文件或文件夹的最后访问时间,从新纪元到访问时的秒数    getmtime(path):文件或文件夹的最后修改时间    getctime(path):文件或文件夹的创建时间    getsize(path):文件或文件夹的大小,若是文件夹返回0    isabs(path):返回是否是绝对路径    isfile(path):返回是否是文件路径    isdir(path):返回是否是文件夹路径    islink(path):返回是否是快捷方式    join(path1,path2,...):将path进行组合,若其中有绝对路径,则之前的path将被删除    normcase(path):转换路径中的间隔符    normpath(path):转换路径为系统可识别的路径    realpath(path):转换路径为绝对路径    split(path):将路径分解为(文件夹,文件名)    splitext(path):将路径分解为(其余部分,.扩展名),若文件名中没有扩展名,扩展名部分为空字符串  在操作与系统不支持的对象时,抛出OSError异常。 2.sys模块  系统信息和方法模块,提供了很多实用的变量和方法:    argv:命令行参数List,第一个元素是程序本身路径    builtin_module_names:Python解释器导入的模块列表    modules.keys():返回所有已经导入的模块列表    exc_info():获取当前正在处理的异常类    exc_type、exc_value、exc_traceback:当前处理的异常详细信息    executable:Python解释程序路径    exit(n):退出程序,正常退出时exit(0)    getwindowsversion():获取Windows的版本    hexversion:获取Python解释程序的版本值,16进制格式如:0x
py3study
2020/01/13
6870
爬虫 (二十二) 最常见的文件操作模块(值得收藏) (十三)
相信如果你慢慢把这篇文章读完,然后加以实践,你会对 python 文件操作会有很大的理解,加油看完哦
公众号---人生代码
2020/01/14
9810
爬虫 (二十二) 最常见的文件操作模块(值得收藏) (十三)
python3基础:目录操作
os模块提供了统一的操作系统接口函数,python中对文件和文件夹的操作都要涉及到os和shutil模块,在使用前需要使用import引入,例如;
py3study
2020/01/09
1.3K0
Python 学习入门(12)—— 文件
python进行文件读写的函数是open或file: f = open(filename, mode)
阳光岛主
2019/02/19
5060
(汇总)os模块以及shutil模块对文件的操作
''' # os 模块 os.sep 可以取代操作系统特定的路径分隔符。windows下为 '\\' os.name 字符串指示你正在使用的平台。比如对于Windows,它是'nt',而对于Linux/Unix用户,它是 'posix' os.getcwd() 函数得到当前工作目录,即当前Python脚本工作的目录路径 os.getenv() 获取一个环境变量,如果没有返回none os.putenv(key, value) 设置一个环境变量值 os.listdir(path) 返回指定目录下的所有文件和目
汪凡
2018/05/29
8920
python学习笔记(一)-文件操作
  fh是打开文件的handle,每一个被打开的文件都应该退出时关闭(除了handle没有赋给变量的文件,如open('filename')。
py3study
2020/01/09
6900
os.path 模块用法详解
总所周知,Windows 操作系统和 Linux 系统存在很多不兼容的地方。文件路径就是一个明显的例子。在 Linux 中,路径的分割采用正斜杠 "/",比如 "/home/monkey";而在 Windows 中,路径分隔采用反斜杠 "\",比如 "C:\Windows\System"。
猴哥yuri
2018/08/16
4490
python 的路径操作
os.sep 表示默认的文件路径分隔符,windows为\, linux为/ os.walk(spath): 用来遍历目录下的文件和子目录 os.listdir(dirname):列出dirname下的目录和文件 os.mkdir() : 创建目录 os.makedirs(): 创建目录,包含中间级目录 os.remove():删除文件,不能是目录 os.rmdir():删除空目录 os.removedirs(path):删除目录及其子目录 os.rename(src, dst) :修改文件名 os.renames(old, new) :修改文件或目录名,包含中间级
py3study
2020/01/10
1.8K0
我是如何用10行代码搬运目标图片的?
嗯呢,你没看错,就是教你把一个路径下的所有目标图片搬运到制定路径下。有读者说:小詹你忽悠人吧,要搬运目标图片复制粘贴不就好了嘛,要什么代码,搬砖脑子秀逗了?
小小詹同学
2019/11/12
1.2K0
我是如何用10行代码搬运目标图片的?
python 图片重命名_python批量重命名文件
** 一个简单的python 脚本,用于图片批量重命名,非常简单但是也非常使用!
全栈程序员站长
2022/10/03
3.5K0
python 图片重命名_python批量重命名文件
关于Python读取文件的路径中斜杠问题
最近用Python读取文件,发现有时候用 '\' 会报错,换成 '\\' 就不会报错。查了下资料发现,'\'是Python的转义字符,如果路径中存在'\t'或者'\r'这样的特殊字符,'\'就无法起到目录跳转的作用,因此报错。解决办法就是告诉系统'\'不是转义字符,'\\'就起这种作用,现给出一个示例。
py3study
2020/01/14
5K0
相关推荐
python 文件和路径操作函数小结
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
本文部分代码块支持一键运行,欢迎体验
本文部分代码块支持一键运行,欢迎体验