版本一
#Filename:backup_ver1.pyimport os
import time
source=[r'F:\Python\hello',r'F:\Python\seq',r'F:\Python\reference.py']
target_dir=r'F:\Python\backup'
target=target_dir + time.strftime('%Y%m%d%H%M%S')+'.zip'
zip_command="zip -qr %s %s"%(target, ' '.join(source))
if (os.system(zip_command)==0):
print 'Successful backup to',target
else:
print 'backup FAIlED'
它如何工作
接下来你将看到我们如何把 设计 一步一步地转换为 代码 。
我们使用了os
和time
模块,所以我们输入它们。然后,我们在source
列表中指定需要备份的文件和目录。目标目录是我们想要存储备份文件的地方,它由target_dir
变量指定。zip归档的名称是目前的日期和时间,我们使用time.strftime()
函数获得。它还包括.zip
扩展名,将被保存在target_dir
目录中。
time.strftime()
函数需要我们在上面的程序中使用的那种定制。%Y
会被无世纪的年份所替代。%m
会被01到12之间的一个十进制月份数替代,其他依次类推。这些定制的详细情况可以在《Python参考手册》中获得。《Python参考手册》包含在你的Python发行版中。注意这些定制与用于print
语句的定制(%
后跟一个元组)类似(但不完全相同)
我们使用加法操作符来 级连 字符串,即把两个字符串连接在一起返回一个新的字符串。通过这种方式,我们创建了目标zip文件的名称。接着我们创建了zip_command
字符串,它包含我们将要执行的命令。你可以在shell(Linux终端或者DOS提示符)中运行它,以检验它是否工作。
zip命令有一些选项和参数。-q
选项用来表示zip命令安静地工作。-r
选项表示zip命令对目录递归地工作,即它包括子目录以及子目录中的文件。两个选项可以组合成缩写形式-qr
。选项后面跟着待创建的zip归档的名称,然后再是待备份的文件和目录列表。我们使用已经学习过的字符串join
方法把source
列表转换为字符串。
最后,我们使用os.system
函数 运行 命令,利用这个函数就好像在 系统 中运行命令一样。即在shell中运行命令——如果命令成功运行,它返回0,否则它返回错误号。
根据命令的输出,我们打印对应的消息,显示备份是否创建成功。好了,就是这样我们已经创建了一个脚本来对我们的重要文件做备份!
给Windows用户的注释
你可以把source
列表和target
目录设置成任何文件和目录名,但是在Windows中你得小心一些。问题是Windows把反斜杠(\)作为目录分隔符,而Python用反斜杠表示转义符!
所以,你得使用转义符来表示反斜杠本身或者使用自然字符串。例如,使用'C:\\Documents'
或r'C:\Documents'
而不是'C:\Documents'
——你在使用一个不知名的转义符\D
!
现在我们已经有了一个可以工作的备份脚本,我们可以在任何我们想要建立文件备份的时候使用它。建议Linux/Unix用户使用前面介绍的可执行的方法,这样就可以在任何地方任何时候运行备份脚本了。这被称为软件的实施环节或开发环节。
上面的程序可以正确工作,但是(通常)第一个程序并不是与你所期望的完全一样。例如,可能有些问题你没有设计恰当,又或者你在输入代码的时候发生了一点错误,等等。正常情况下,你应该回到设计环节或者调试程序。
版本二
第一个版本的脚本可以工作。然而,我们可以对它做些优化以便让它在我们的日常工作中变得更好。这称为软件的维护环节。
我认为优化之一是采用更好的文件名机制——使用 时间 作为文件名,而当前的 日期 作为目录名,存放在主备份目录中。这样做的一个优势是你的备份会以等级结构存储,因此它就更加容易管理了。另外一个优势是文件名的长度也可以变短。还有一个优势是采用各自独立的文件夹可以帮助你方便地检验你是否在每一天创建了备份,因为只有在你创建了备份,才会出现那天的目录。
#Filename:backup_ver2.pyimport os
import time
source=[r'F:\Python\hello',r'F:\Python\seq',r'F:\Python\reference.py']
target_dir=r'F:\Python\backup'
today=target_dir+time.strftime('%Y%m%d')
now=time.strftime('%H%M%S')
if not os.path.exists(today):
os.mkdir(today)
print 'Successfully created directory',today
target=today+os.sep+now+'.zip'
zip_command="zip -qr %s %s" % (target,' '.join(source))
if os.system(zip_command)==0:
print 'Successful backup to',target
else:
print 'backup failed'
版本三
第二个版本在我做较多备份的时候还工作得不错,但是如果有极多备份的时候,我发现要区分每个备份是干什么的,会变得十分困难!例如,我可能对程序或者演讲稿做了一些重要的改变,于是我想要把这些改变与zip归档的名称联系起来。这可以通过在zip归档名上附带一个用户提供的注释来方便地实现
#Filename:backup_ver3.pyimport os
import time
source=[r'F:\Python\hello',r'F:\Python\seq',r'F:\Python\reference.py']
target_dir=r'F:\Python\backup'
today=target_dir+time.strftime('%Y%m%d')
now=time.strftime('%H%M%S')
comment = raw_input("Enter a comment-->")
if len(comment)==0:
target=today+os.sep+now+'.zip'
else:
target=today+os.sep+now+'_'+comment.replace(' ','_')+'.zip'
if not os.path.exists(today):
os.mkdir(today)
print 'Successfully created directory',today
zip_command="zip -qr %s %s" % (target,' '.join(source))
if os.system(zip_command)==0:
print 'Successful backup to',target
else:
print 'backup failed'
它如何工作
这个程序现在工作了!让我们看一下版本三中作出的实质性改进。我们使用raw_input
函数得到用户的注释,然后通过len
函数找出输入的长度以检验用户是否确实输入了什么东西。如果用户只是按了回车(比如这只是一个惯例备份,没有做什么特别的修改),那么我们就如之前那样继续操作。
然而,如果提供了注释,那么它会被附加到zip归档名,就在.zip
扩展名之前。注意我们把注释中的空格替换成下划线——这是因为处理这样的文件名要容易得多。