如何将循环遍历的文件路径传入仅接受原始字符串的函数?
问题:Shell.NameSpace无法接收变量路径获取文件元数据
背景
我正在写一个生成目录内容报告的脚本,输出为CSV格式,每份报告用唯一时间戳命名,避免覆盖或追加到同一文件。报告的列头是:
header = ['File_Pathway', 'Subdir', 'File_Name', 'Extension', 'Size_(in_bytes)', 'File_Created', 'Last_File_Save_Date', 'File_Author', 'Last_Saved_By_User_X']
其中File_Author和Last_Saved_By_User_X这两个字段一直拿不到,后来找到一段通过文件元数据收集信息的脚本:
import win32com.client sh=win32com.client.gencache.EnsureDispatch('Shell.Application',0) ns = sh.NameSpace(r'm:\music\Aerosmith\Classics Live!') colnum = 0 columns = [] while True: colname=ns.GetDetailsOf(None, colnum) if not colname: break columns.append(colname) colnum += 1 for item in ns.Items(): print (item.Path) for colnum in range(len(columns)): colval=ns.GetDetailsOf(item, colnum) if colval: print('\t', columns[colnum], colval)
遇到的问题
这段脚本里sh.NameSpace用的是原始字符串写法,但我需要传入遍历目录时的current_filepath变量。试了各种把字符串转成原始字符串的方法都没用,求解决。
附上我脚本里current_filepath的相关代码片段:
rootdir = input('Enter directory pathway: ') count = 0 datetime_for_filename = datetime.now() datetime_for_filename_format = str(datetime.strftime(datetime_for_filename, '%Y-%m-%d--%H-%M-%S')) filename_with_datetimestamp = 'filename_printout' + '-' + datetime_for_filename_format + '.csv' header = ['File_Pathway', 'Subdir', 'File_Name', 'Extension', 'Size_(in_bytes)', 'File_Created', 'Last_File_Save_Date', 'File_Author', 'Last_Saved_By_User_X'] for subdir, dirs, files in os.walk(rootdir): with open(filename_with_datetimestamp, 'a', newline='') as f: writer = csv.writer(f) current_subdir = subdir try: for filenames in files: data_list = [] current_filepath = subdir + '\\' + filenames raw_current_filepath = fr"{current_filepath}"
解决方法
先说清楚:sh.NameSpace根本不需要原始字符串,它接受普通字符串路径。原始字符串只是写代码时为了避免转义的写法,变量本身就是字符串,直接传就行。真正的问题是你传错了路径类型——它要的是目录路径,不是单个文件路径!
修正后的完整代码示例
import win32com.client import os import csv from datetime import datetime def get_file_metadata(file_path): sh = win32com.client.gencache.EnsureDispatch('Shell.Application') # 获取文件所在的目录路径 dir_path = os.path.dirname(file_path) ns = sh.NameSpace(dir_path) if not ns: return None # 先枚举当前目录所有可用的元数据列 columns = [] colnum = 0 while True: colname = ns.GetDetailsOf(None, colnum) if not colname: break columns.append(colname) colnum += 1 # 在目录项中找到目标文件 file_name = os.path.basename(file_path) file_item = None for item in ns.Items(): if item.Name == file_name: file_item = item break if not file_item: return None # 提取需要的元数据 metadata = {} for colnum in range(len(columns)): colval = ns.GetDetailsOf(file_item, colnum) if colval: metadata[columns[colnum]] = colval return metadata # 主脚本逻辑 rootdir = input('请输入目录路径: ') datetime_for_filename = datetime.now() datetime_for_filename_format = datetime.strftime(datetime_for_filename, '%Y-%m-%d--%H-%M-%S') filename_with_datetimestamp = f'filename_printout-{datetime_for_filename_format}.csv' header = ['File_Pathway', 'Subdir', 'File_Name', 'Extension', 'Size_(in_bytes)', 'File_Created', 'Last_File_Save_Date', 'File_Author', 'Last_Saved_By_User_X'] # 先写入CSV表头(只写一次) with open(filename_with_datetimestamp, 'w', newline='', encoding='utf-8-sig') as f: writer = csv.writer(f) writer.writerow(header) # 遍历目录所有文件 for subdir, dirs, files in os.walk(rootdir): for filename in files: current_filepath = os.path.join(subdir, filename) data_list = [] # 填充基础文件信息 data_list.append(current_filepath) data_list.append(subdir) data_list.append(filename) # 提取扩展名(去掉开头的点) ext = os.path.splitext(filename)[1] data_list.append(ext[1:] if ext else '') data_list.append(os.path.getsize(current_filepath)) # 转换时间格式为可读字符串 data_list.append(datetime.fromtimestamp(os.path.getctime(current_filepath)).isoformat()) data_list.append(datetime.fromtimestamp(os.path.getmtime(current_filepath)).isoformat()) # 获取元数据并提取作者和最后保存人 metadata = get_file_metadata(current_filepath) # 注意:元数据列名随系统语言变化,中文系统可能是"作者"、"最后保存者",英文是"Author"、"Last Saved By" file_author = metadata.get('Author', '') if metadata else '' last_saved_by = metadata.get('Last Saved By', '') if metadata else '' data_list.append(file_author) data_list.append(last_saved_by) # 写入CSV行 with open(filename_with_datetimestamp, 'a', newline='', encoding='utf-8-sig') as f: writer = csv.writer(f) writer.writerow(data_list)
关键注意点
- 路径传递问题:
sh.NameSpace必须传目录路径,不能传单个文件路径,所以要先用os.path.dirname()从文件路径中提取目录 - 原始字符串误区:变量形式的字符串不需要转成原始字符串,直接传就行,原始字符串只是写死路径时的语法糖
- 路径拼接:用
os.path.join()替代手动拼接+ '\\',避免跨系统路径分隔符问题 - 表头写入:表头只需要写入一次,不要放在循环里反复打开文件追加
- 元数据列名:列名会随系统语言变化,比如中文系统里"Author"会变成"作者",需要根据自己的系统调整字典的键名
内容的提问来源于stack exchange,提问作者Katherine Jarzecki
相关产品推荐
相关产品推荐

