2007-08-01
Python Cookbook 2.29 为文件名添加版本号
需求:
你需要对文件进行备份,在备份的时候,想给文件名添加标准的3位数版本号.如.001.
讨论:
我们要写代码来实现这个功能:
def VersionFile(file_spec, vtype='copy'):
import os, shutil
if os.path.isfile(file_spec):
# check the 'vtype' parameter
if vtype not in ('copy', 'rename'):
raise ValueError, 'Unknown vtype %r' % (vtype,)
# Determine root filename so the extension doesn't get longer
n, e = os.path.splitext(file_spec)
# Is e a three-digits integer preceded by a dot?
if len(e) == 4 and e[1:].isdigit( ):
num = 1 + int(e[1:])
root = n
else:
num = 0
root = file_spec
# Find next available file version
for i in xrange(num, 1000):
new_file = '%s.%03d' % (root, i)
if not os.path.exists(new_file):
if vtype == 'copy':
shutil.copy(file_spec, new_file)
else:
os.rename(file_spec, new_file)
return True
raise RuntimeError, "Can't %s %r, all names taken"%(vtype,file_spec)
return False
if _ _name_ _ == '_ _main_ _':
import os
# create a dummy file 'test.txt'
tfn = ' test.txt'
open(tfn, 'w').close( )
# version it 3 times
print VersionFile(tfn)
# emits: True
print VersionFile(tfn)
# emits: True
print VersionFile(tfn)
# emits: True
# remove all test.txt* files we just made
for x in ('', '.000', '.001', '.002'):
os.unlink(tfn + x)
# show what happens when the file does not exist
print VersionFile(tfn)
# emits: False
print VersionFile(tfn)
# emits: False
上面代码的目的是在你更新文件内容之前,确保它已经被复制或者重命名(由参数决定),在你修改文件之间,备份它们是一个比较好的习惯.最终进行复制和重命名操作的是shutil.copy和os.rename ,所以问题的核心就是要找到需要操作的文件名.
判断备份文件的一种流行的方式就是版本号,本节获取新文件名的方法是首先获得它的原始文件名(如果文件以前有版本号的话),然后为文件添加版本号,如.000,.001,直到没有重复的文件名存在为止.此时,使用文件重命名方法来修改文件名.需要注意的是VersionFile函数只能判断1000个版本号,在你使用它之前需要明白这一点.在文件备份之前,它必须存在,否则你无法操作(MS废话),当然,如果文件不存在,VersionFile会返回False(当成功执行改名后返回True;),所以你也不用在使用它前来写代码判断文件是否存在.
相关说明:
os.rename(...)
rename(old, new)
Rename a file or directory.
shutil.copy(src, dst)
Copy data and mode bits ("cp src dst").
The destination may be a directory.
你需要对文件进行备份,在备份的时候,想给文件名添加标准的3位数版本号.如.001.
讨论:
我们要写代码来实现这个功能:
def VersionFile(file_spec, vtype='copy'):
import os, shutil
if os.path.isfile(file_spec):
# check the 'vtype' parameter
if vtype not in ('copy', 'rename'):
raise ValueError, 'Unknown vtype %r' % (vtype,)
# Determine root filename so the extension doesn't get longer
n, e = os.path.splitext(file_spec)
# Is e a three-digits integer preceded by a dot?
if len(e) == 4 and e[1:].isdigit( ):
num = 1 + int(e[1:])
root = n
else:
num = 0
root = file_spec
# Find next available file version
for i in xrange(num, 1000):
new_file = '%s.%03d' % (root, i)
if not os.path.exists(new_file):
if vtype == 'copy':
shutil.copy(file_spec, new_file)
else:
os.rename(file_spec, new_file)
return True
raise RuntimeError, "Can't %s %r, all names taken"%(vtype,file_spec)
return False
if _ _name_ _ == '_ _main_ _':
import os
# create a dummy file 'test.txt'
tfn = ' test.txt'
open(tfn, 'w').close( )
# version it 3 times
print VersionFile(tfn)
# emits: True
print VersionFile(tfn)
# emits: True
print VersionFile(tfn)
# emits: True
# remove all test.txt* files we just made
for x in ('', '.000', '.001', '.002'):
os.unlink(tfn + x)
# show what happens when the file does not exist
print VersionFile(tfn)
# emits: False
print VersionFile(tfn)
# emits: False
上面代码的目的是在你更新文件内容之前,确保它已经被复制或者重命名(由参数决定),在你修改文件之间,备份它们是一个比较好的习惯.最终进行复制和重命名操作的是shutil.copy和os.rename ,所以问题的核心就是要找到需要操作的文件名.
判断备份文件的一种流行的方式就是版本号,本节获取新文件名的方法是首先获得它的原始文件名(如果文件以前有版本号的话),然后为文件添加版本号,如.000,.001,直到没有重复的文件名存在为止.此时,使用文件重命名方法来修改文件名.需要注意的是VersionFile函数只能判断1000个版本号,在你使用它之前需要明白这一点.在文件备份之前,它必须存在,否则你无法操作(MS废话),当然,如果文件不存在,VersionFile会返回False(当成功执行改名后返回True;),所以你也不用在使用它前来写代码判断文件是否存在.
相关说明:
os.rename(...)
rename(old, new)
Rename a file or directory.
shutil.copy(src, dst)
Copy data and mode bits ("cp src dst").
The destination may be a directory.