解决问题

我们已经探索了 Python 语言中的许多部分,现在我们将通过设计并编写一款程序来了解如何把这些部分组合到一起。这些程序一定是能做到一些有用的事情。这节的Python教程就是教大家方法去学习如何靠你自己来编写一份 Python 脚本。

问题

我们希望解决的问题如下:

我想要一款程序来备份我所有的重要文件。

虽然这是一个简单的问题,但是其中并没有足够的信息有助于让我们开始规划一份解决方案。我们需要进行一些分析(Analysis)。例如,我们应该如何指定哪些文件是我们需要备份的?它们应该如何进行备份?储存到哪里?

在正确地分析了这些问题过后,我们便开始设计(Design)我们的程序。我们将列出一份关于我们的程序应如何运转的清单。在这个案例中,我已经编写了如下清单来说明将如何工作。如果由你来设计程序,你可能不会做出同样的分析,因为每个人都有其自己的行事方式,所以出现不同是完全正常、且正确的。

  • 需要备份的文件与目录应在一份列表中予以指定。
  • 备份必须存储在一个主备份目录中。
  • 备份文件将打包压缩成 zip 文件。
  • zip 压缩文件的文件名由当前日期与时间构成。
  • 我们使用在任何 GNU/Linux 或 Unix 发行版中都会默认提供的标准 zip 命令进行打包。在这里你需要了解到只要有命令行界面,你就可以使用任何需要用到的压缩或归档命令。

针对 Windows 用户的提示

Windows 用户可以从 GnuWin32 项目页面 上下载并安装 zip 命令,并将 C:\Program Files\GnuWin32\bin 添加至你的系统的 PATH 环境变量中,这一操作过程与我们为使系统识别 Python 命令本身所做的事情相同。

解决方案

由于我们的程序设计方案现在已经相当稳定,我们便可以开始编写代码,这个过程我们称之为实现(Implementation)我们的解决方案。

将下述代码保存为 backup_ver1.py

import os
import time # 1. 需要备份的文件与目录将被
# 指定在一个列表中。
# 例如在 Windows 下:
# source = ['"C:\\My Documents"', 'C:\\Code']
# 又例如在 Mac OS X 与 Linux 下:
source = ['/Users/swa/notes']
# 在这里要注意到我们必须在字符串中使用双引号
# 用以括起其中包含空格的名称。 #2. 备份文件必须存储在一个
#主备份目录中
#例如在 Windows 下:
# target_dir = 'E:\\Backup'
# 又例如在 Mac OS X 和 Linux 下:
target_dir = '/Users/swa/backup'
# 要记得将这里的目录地址修改至你将使用的路径 # 3. 备份文件将打包压缩成 zip 文件。
# 4. zip 压缩文件的文件名由当前日期与时间构成。
target = target_dir + os.sep + \
time.strftime('%Y%m%d%H%M%S') + '.zip' # 如果目标目录还不存在,则进行创建
if not os.path.exists(target_dir):
os.mkdir(target_dir) # 创建目录 # 5. 我们使用 zip 命令将文件打包成 zip 格式
zip_command = 'zip -r {0} {1}'.format(target,
' '.join(source)) # 运行备份
print('Zip command is:')
print(zip_command)
print('Running:')
if os.system(zip_command) == 0:
print('Successful backup to', target)
else:
print('Backup FAILED')
输出: $ python backup_ver1.py
Zip command is:
zip -r /Users/swa/backup/20140328084844.zip /Users/swa/notes
Running:
adding: Users/swa/notes/ (stored 0%)
adding: Users/swa/notes/blah1.txt (stored 0%)
adding: Users/swa/notes/blah2.txt (stored 0%)
adding: Users/swa/notes/blah3.txt (stored 0%)
Successful backup to /Users/swa/backup/20140328084844.zip

现在,我们正处于测试(Testing)阶段,在这一阶段我们测试我们的程序是否能正常工作。如果其行为不符合我们的预期,那么我们需要对我们的程序进行 Debug 工作,也就是说,移除程序中的 Bug(错误)。

如果上面的程序不能够正常工作,复制打印在 Zip command is 后面的命令,将其粘贴至 shell(在 GNU/Linux 与 Mac OS X 环境中)或 cmd(对于 Windows 环境),看看存在什么错误并尝试将其修复。同时你还需要检查 zip 命令手册来看看是不是哪里存在错误。如果这条命令成功运行,那么可能是错误可能存在在 Python 程序本身之中,因此你需要检查你的程序是否如上面所展示那番。

它是如何工作的

你会注意到我们是如何一步步将我们的设计转化为代码的。

我们首先导入 os 与 time 模块以准备使用它们。然后,我们在 source 列表中指定我们需要备份的文件与目录。我们需要存储我们所有备份文件的目标目录在 target_dir 变量中予以指定。我们将要创建的 zip 归档文件的名字由当前日期与时间构成,在这里通过 time.strftime() python函数来创建。文件名将以 .zip 作为扩展名,并存储在 target_dir 目录中。

在这里要注意 os.sep 变量的使用方式——它将根据你的操作系统给出相应的分隔符,在 GNU/Linux 与 Unix 中它会是 '/',在 Windows 中它会是 '\\',在 Mac OS 中它会是 ':'。使用 os.sep 而非直接使用这些字符有助于使我们的程序变得可移植,从而可以在上述这些系统中都能正常工作。

time.strftime() 函数会遵循某些格式(Specification),其中一种就如我们在上方程序中所使用的那样。%Y 将被替换成带有具体世纪的年份。%m 将会被替换成以 01 至 12 的十进制数所表示的月份。有关这些格式的全部列表可以在 Python 参考手册中查询到。

我们使用连接(Concatenates)字符串的加法(+)运算符来创建目标 zip 文件的文件名,也就是说,它将两个字符串连接到一起并返回一个新的字符串。然后,我们创建了一串字符串 zip_command,其中包括了我们要执行的命令。如果这条命令不能正常工作,你可以把它拷贝到 Shell(GNU/Linux 终端或 DOS 提示符)中进行检查。

我们使用的 zip 命令会有一些选项与参数需要传递。-r 选项用以指定 zip 命令应该递归地(Recursively)对目录进行工作,也就是说它应该包括所有的子文件夹与其中的文件。这两个选项结合到一起并可以指定一个快捷方式作 -qr。选项后面跟着的是将要创建的 zip 文件的名称,再往后是需要备份的文件与目录的列表。我们通过使用已经讨论过并已了解该如何运用的的字符串方法 join 来将列表 source转换成字符串。

随后,我们终于可以运行这一使用了 os.system 函数的命令,这一函数可以使命令像是从系统中运行的。也就是说,从 shell 中运行的——如果运行成功,它将返回 0,如果运行失败,将返回一个错误代码。

根据命令运行的结果是成功还是失败,我们将打印出与之相应的信息来告诉你备份的结果究竟如何。

就是这样,我们便创建了一份用以备份我们的重要文件的脚本!

针对 Windows 用户的提示

除了使用双反斜杠转义序列,你还可以使用原始字符串。例如使用 'C:\\Documents' 或 r'C:\Documents'。然而,要使用 'C:\Documents',因为它将被识别为你使用了一个未知的转义序列 \D 来结束路径的输入。

现在,我们已经拥有了一份可以正常工作的备份脚本,我们可以在任何我们需要备份文件的时候使用它。这被称作软件的操作(Operation)部署(Deployment)阶段。

上面所展示的程序能够正常工作,但是(通常)第一个程序都不会按照你所期望的进行工作。可能是因为你没有正确地设计程序,或如果你在输入代码时出现了错误。出现这些情况时,在恰当的时候,你需要回到设计阶段,或者你需要对你的程序进行 Debug 工作。

自己来编写一份 Python 脚本 第一版的更多相关文章

  1. [小技巧] Python 脚本暴力破解 HC2600 机顶盒管理密码

    家里最近接入了广电有线电视,配了三个创维 HC2600 机顶盒,并且每个机顶盒还带有无线路由器功能. 免费赠送 Internet 接入服务倒也没什么,不过机顶盒内置的 WIFI 实在有点寒酸:只支持 ...

  2. SecureCRT中python脚本编写

    SecureCRT中python脚本编写学习指南 SecureCRT python 引言 在测试网络设备中,通常使用脚本对设备端进行配置和测试以及维护:对于PE设备的测试维护人员来说使用较多是Secu ...

  3. python脚本初探---新手如何直接编写一个hello world模块即可执行的.py文件

    废话不多说,就讲一下这个背景吧: 事情是这个样子的~ 本着好学的精神,咱就买了本书,学习python结果呢,发现python的教程都是一个样子滴,上来的第一个hello world 都是通过IDLE来 ...

  4. python编写Mysql自动备份脚本

    1、先写一个python脚本 vim /opt/mysql_dump.py #!/usr/bin/env python# -*- coding:utf-8 -*-import osimport tim ...

  5. 【python入门】之教你编写自动获取金币脚本

    本文作者:青衫磊落 最近看到个特别全面源码分享网站,刚好有个项目是一直想做但是没有头绪的,就想下载学习一下.注册账号后,发现还需要若干金币.后来发现可以通过每隔一定时间发心情状态来获得金币,就打算写一 ...

  6. vim—自动缩进(编写Python脚本)

    大神推荐使用vim编写Python脚本,学而时积之,不亦乐乎! 使用vim编写Python脚本的时候不能正常缩进,需要修改vimrc文件 Ubuntu系统下vimrc文件的位置: $ cd /etc/ ...

  7. 编写Python脚本把sqlAlchemy对象转换成dict的教程

    编写Python脚本把sqlAlchemy对象转换成dict的教程 在用sqlAlchemy写web应用的时候,经常会用json进行通信,跟json最接近的对象就是dict,有时候操作dict也会比操 ...

  8. 一次针对多台服务器交互式主机命令采集Python脚本编写

    [环境介绍]   系统环境:Linux + Python 2.7.10(监控主机)   [背景描述] 需求:每次节假日或者重要时间时,需要对数据库主机信息进行检查,比如主机空间使用率之类.有时候需要执 ...

  9. window下编写python脚本在linux下运行出错 usr/bin/python^M: bad interpreter: No such file or directory

    今天在windows下使用notepad++写了个python脚本,传到linux服务器执行后提示:-bash: ./logger.py: usr/bin/python^M: bad interpre ...

随机推荐

  1. [转]C# 指针之美

     将C#图像库的基础部分开源了(https://github.com/xiaotie/GebImage).这个库比较简单,且离成熟还有一段距离,但它是一种新的开发模式的探索:以指针和非托管内存为主的C ...

  2. 11572 - Unique Snowflakes(贪心,两指针滑动保存子段最大长度)

    Emily the entrepreneur has a cool business idea: packaging and selling snowflakes. She has devised a ...

  3. iOS/Swift Tips 1

    1.重写hitTest方法,干预iOS事件传递过程 如下所示,view上有一个button,button一半的frame在父类view bounds之外, 按照iOS系统默认的处理逻辑, 如果点击按钮 ...

  4. 破损的键盘(悲剧文本)(Broken Keyboard(a.k.a. Beiju Text),Uva 11988)

    破损的键盘(悲剧文本)(Broken Keyboard(a.k.a. Beiju Text),Uva 11988) 题意描述 你在输入文章的时候,键盘上的Home键和End键出了问题,会不定时的按下. ...

  5. ubnutu 安装protocol buffer

    工作中需要使用protocol buffer,需要编译出protocol buffer的动态链接库,然后在别的makefile中链接它, 我的环境是ubnutu16.04,64bit,使用的proto ...

  6. 数据库与python的连接

    db=web.database( dbn="mysql", host="localhost", port=3306, user="root" ...

  7. php 算法(二分法)只适用于有序表,且限于顺序存储结构

    function demo($array,$low,$high,$k){ if($low<=$high){//判断该数组是否存在 $mid =  intval(($low+$high)/2 ); ...

  8. laravel 安装添加多站点

    官方文档如下 https://learnku.com/laravel/t/1160/laravel-nginx-multi-site-configuration

  9. 数据仓库和Hadoop大数据平台有什么差别?

    广义上来说,Hadoop大数据平台也可以看做是新一代的数据仓库系统, 它也具有很多现代数据仓库的特征,也被企业所广泛使用.因为MPP架构的可扩展性,基于MPP的数据仓库系统有时候也被划分到大数据平台类 ...

  10. sql server 常用sql语句

    --删除约束 alter table productInfo drop constraint 约束名称 --删除列alter table productInfo drop column 列名 --添加 ...