我已经阅读过有关此错误的先前文章。但是,这对我没有帮助。因此,我再次提请注意。代码如下。
import os
replacements = {':': '_', '+': '_'}
for fn in os.walk('/media/ambijat/Dataworld/f23/Dropbox/ttgis'):
nn = fn
for k, v in replacements.items():
nn = nn.replace(str(k), str(v))
if nn != fn:
os.rename(fn, nn)
此命令在运行时出现错误'tuple' object has no attribute 'replace'
,并且似乎出现了错误。我正在使用dict替换文件名中的特殊字符,例如[,&<>*?|\";+:'() ]
。有没有更好的办法做到这一点。谢谢。
答案 0 :(得分:4)
os.walk
产生元组:
对于树根目录中的每个目录 目录顶部(包括顶部本身),它会生成一个 3元组(目录路径, 目录名,文件名)。
要仅提取文件名,请使用索引或序列解压缩。这些都可以使用:
nn = fn[-1]
nn = fn[2]
_, _, nn = fn
或者,正如@AntonvBR指出的那样,您可以在for
可迭代循环的定义中使用序列解压缩:
for _, _, fn in os.walk('/media/ambijat/Dataworld/f23/Dropbox/ttgis'):
nn = fn
# as before..
答案 1 :(得分:2)
在您的第一段代码中,fn
是一个元组,因为os.walk()
返回一个dirpath(字符串),dirnames(列表),文件名(list)的元组。因此,当将其分配给nn
时,nn
成为元组,而依次使用nn.replace(k, v)
将不起作用,因为元组没有方法replace
。
在第二段代码中,nn
现在等于fn[2]
(目录名列表)。不幸的是,列表也没有replace
方法。假设您要替换文件名中的所有:
和+
,则需要遍历以下每个文件名:
我在代码中观察到并更改的其他内容:
os.walk
返回的文件名不包含文件的完整路径,这意味着如果脚本不在与您所在的目录相同的目录中运行,os.rename
可能找不到文件重命名文件。因此,我也在重命名期间合并了path
。os.rename
之后,目录中的文件将被重命名,但是代码读取的文件名仍将相同。因此,您还必须在代码中更改文件名。所以:
import os
replacements = {':': '_', '+': '_'}
for fn in os.walk('/media/ambijat/Dataworld/f23/Dropbox/ttgis'):
path = fn[0]
nn = fn[2]
for filename in nn:
newname = filename
for k, v in replacements.items():
newname = newname.replace(str(k), str(v))
if newname != filename:
os.rename(os.path.join(path, filename), os.path.join(path, newname))
filename = newname
尽管我会通过以下建议再减少一条代码行:
import os
replacements = {':': '_', '+': '_'}
for path, _, filenames in os.walk('/media/ambijat/Dataworld/f23/Dropbox/ttgis'):
for filename in filenames:
newname = filename
for k, v in replacements.items():
newname = newname.replace(k, v)
if newname != filename:
os.rename(os.path.join(path, filename), os.path.join(path, newname))
filename = newname
答案 2 :(得分:0)
问题在于线路
nn = nn.replace(str(k), str(v))
os.walk
根据the Python docs返回一个(dirpath, dirnames, filenames)
形式的元组序列。因此,您尝试在元组上调用.replace()
方法,这会给您带来错误,因为tuple
类没有这样的方法。我认为您打算使用str.replace()
方法。
以下一些代码应该可以工作(在我为此目的在我的计算机上创建的某些目录中进行了测试):
import os
replacements = {':': '_', '+': '_'}
for directory in os.walk('/media/ambijat/Dataworld/f23/Dropbox/ttgis'):
filenames = directory[-1]
for k, v in replacements.items():
for filename in filenames:
newname = filename.replace(k, v)
if newname != filename:
os.rename(directory[0]+'\\'+filename, directory[0]+'\\'+newname)