文档章节

Python 编写自动化工具

Yomut
 Yomut
发布于 2017/09/05 21:45
字数 2720
阅读 28
收藏 2

 

引言:

在开发过程中,我们经常需要编写一些自动化的工具,例如:

  • Windows 下的 BATCH (批处理)
  • Linux 下的 Shell 等

但是假如我们要做跨平台的开发,根据每个平台去开发一套功能相同的自动化脚本显然不是最好的选择,选择跨平台通用的脚本是更好的选择,Python 就是常用来编写自动化工具的跨平台脚本语言。

Python 环境安装:

1.资源下载:

直接到 Python 官网 下载安装包,有两个分支:2.x 和 3.x,两者有着巨大的差别,当然现在比较流行的还是 2.7.x 系列,这里我直接下载此系列的最新版本:python-2.7.13.msi 。

2.安装步骤:

过程十分简单,双击打开安装包,一直 Next 直到安装完成,记得要记录一下其安装目录,后面配置系统环境时要用到。

3.环境配置:

打开 计算机 -> 属性 -> 高级系统设置 -> 环境变量... ,然后再 系统变量 中新建一项,设置参数如下:

变量名:PYTHON_HOME
变量值:D:\Develope\Python2.7

然后编辑系统变量中的 Path 变量的参数,在变量值最后加上 ;%PYTHON_HOME%;,然后保存编辑内容。然后,打开命令行窗口查询是否配置成功:

C:\Users\hasee-pc>python --version
Python 2.7.13

以上说明环境变量的配置已完成。

4.运行 Python:

运行 Python 代码块的方式有两种,一种是直接在命令行窗口输入 Python 指令进入交互式编程窗口,然后直接输入代码,键盘 Enter 执行结果,如下:

C:\Users\hasee-pc>python
Python 2.7.13 (v2.7.13:a06454b1afa1, Dec 17 2016, 20:42:59) [MSC v.1500 32 bit (
Intel)] on win32
Type "help", "copyright", "credits" or "license" for more information.
>>> print "hi,linsh"
hi,linsh

也可以创建一个 .py 脚本,编辑好脚本内容,例如:

# test.py
print "hi,linsh"

然后,在命令行定位到脚本所在目录,执行该脚本,以下两种执行方式都可以:

D:\Develope\PythonProjects>python test.py
hi,linsh
D:\Develope\PythonProjects>test.py
hi,linsh

# 号用于注释单行,多行注释通常使用三引号 ''' 或 """ 开始和结束。

Python 基础语法:

这里不会赘述太多细节性的语法,只简述一些必要的基础语法,更详细的可以参考 【 Python 语言参考 】:

1.特殊标识符:

  • 跟其他编程语言一样,Python 中所有标识符可以包含:英文、数字以及下划线(_),但不能以数字开头;
  • 以下划线开头的表示特殊含义: 
    • 单下划线 _ 开头表示不能直接被外部类直接访问的类属性,,需要通过类提供的接口才能进行访问,例如:_foo
    • 双下划线 __ 开头表示类的私有成员,就像很多语言中的 private 权限关键字的作用,例如:__foo
    • 以双下划线开头和结尾代表 Python 中特殊方法专用的标识,例如 __init__() 代表类的构造函数。

2.缩进和代码块:

Python 与其他语言最大的不同,在于它不使用 {} 或者像 Lua 那样的关键字来包裹一个代码块以管理类、函数或逻辑判断,而是直接通过 缩进 来管理模块。

缩进的空白 数量(键盘空格键次数)是可变的,但是所有代码块语句必须包含相同的缩进空白数量。例如:

if True:
    print "True"
else:
    print "False"

通常将编程工具的一次 Tab 键的距离设为 4 个空格 距离,作为一级缩进的空白数。

3.数据类型和变量:

Python 有 5 种标准的数据类型:

Numbers(数字)
String(字符串)
List(列表)
Tuple(元组)
Dictionary(字典)

但是,在定义变量时,不需要声明变量的类型,变量在使用前需要先进行赋值,此时解释器才能根据赋值的类型为此变量分配创建内存空间并创建此变量,只是声明但不赋值的变量是不能使用的。例如:

number = 2      # 整型
percent = 100.0 # 浮点型
name = "linsh"  # 字符串

此外,还可以同时对多个变量进行赋值:

number,percent,name = 2,100.0,"linsh"

4.函数:

函数的使用一方面是为了提高代码的重用性,另一方面又可以增强代码的可读性和模块化,下面是 Python 定义函数的格式:

def funcName(param1,param2,...):
    ...

以关键字 def 来声明一个函数,紧跟着是函数名(函数标识符),然后是 () 包围起来的传入参数表,可以是 0 个参数,也可以是多个参数,然后用 : 号开始函数内容的开始。例如:

# test.py
# # -*- coding: utf-8 -*-

# 方法定义
def TestFunc1():
    print "test1"

def TestFunc2(num):
    print "test2: num = ",num #str 和 int 类型拼接

# 方法调用
TestFunc1()
TestFunc2(66)

执行结果:

D:\Develope\PythonProjects>test.py
test1
test2: num =  66

编写工具:

1.设计目标:

首先说一下我要工具的功能:

遍历某个目录下包括其下子目录中所有指定的后缀文件,然后为这些文件的头部插入指定的字符串。

2.使用场景:

设计这样的工具起因是我最近在将之前 CSDN 中的博客搬运到自己的 Hexo 博客空间上,了解的应该知道,假如都是 Markdown 编写的话,搬运的时候只需要在文件头部加上如下的一串额外的内容:

---
title: 博客标题
date: 博客创建时间(例如:2016-09-03 17:15:22)
tags: 标签(如:[Hexo,Next],多个的话用,号隔开)
categories: 分类(如:Web)
---
  • 标题 title 直接使用文件名称去掉 .md 后缀即可;
  • 时间 date 需要通过文件库获取文件的创建时间;
  • 标签 tags 和分类 categories ,由于我的文件会根据分类放入不同的子目录下,所以直接获取当前文件所在目录的名称即可。

此外,为了在博客首页只展示部分内容,而不是展开博客的完整内容,还需要在博客中恰当的位置插入这个标签:<!--more--> ,通常加载第一段内容结束的位置。

3.实现代码:

根据上面的思路,我们在 source/_posts 目录下创建一个工具脚本,起名为 SuitFileToHexo.py ,然后依次完成以下步骤:

  • 指定 Linux 环境下 Python 解释器目录,并指定编码方式:

    
    #!/usr/bin/env python
    
    
    # -*- coding: utf-8 -*-
    
  • 引入的模块:

    在脚本开始的地方,最先需要做的事情就是把需要用到的模块都先引入进来,大致分析一下我们这个功能需要用到的模块:

    import os.path,time
    •  
  • 遍历当前目录下所有 .md 文件列表:

    这就需要使用到 Python 的文件目录操作模块 os.path ,使用 os.listdir 获取目录列表,然后通过 os.path.splitext 分割文件名称和后缀名,从而筛选合格的文件:

    
    # 获取指定目录指定后缀名的文件列表
    
    def getFileList(path,endStr):
    '''获取指定目录下,指定后缀的文件列表'''
    r_list = []
    f_list = os.listdir(path)   #获取目录列表
    for i in f_list:
        # 分离文件名和后缀名,过滤掉工具脚本
        file_endStr = os.path.splitext(i)[1]
        # 判断是否是目录
        if os.path.isdir(i):
            f_list1 = os.listdir(path+'/'+i)
            for j in f_list1:
                # 过滤出指定后缀 endStr 后缀的文件
                if os.path.splitext(j)[1] == endStr:
                    # 为了清晰目录把文件所在目录也标识出来
                    r_list.append(i+'/'+j)
                    # print j.decode("string_escape")
        elif file_endStr == endStr:
            r_list.append(i)
    return r_list
  • 获取文件的创建时间:

    需要使用到 os.time 模块的功能:

    
    # 获取文件创建时间
    
    def get_FileCreateTime(filePath):
    t = os.path.getctime(filePath)
    return TimeStampToTime(t)
    
    
    # 把时间戳转化为时间: 1479264792 to 2016-11-16 10:53:12'''
    
    def TimeStampToTime(timestamp):
    timeStruct = time.localtime(timestamp)
    return time.strftime('%Y-%m-%d %H:%M:%S',timeStruct)
  • 获取博客标题:

    其实就是从目录字符串中截掉后缀名,再截掉最后一个 / 之前的内容即可得到博客名称:

    
    # 获取目录中去掉前面路径和后缀的文件名字
    
    def getFileSimpleName(filePath):
    name = ''
    
    # 先去掉后缀
    
    name = os.path.splitext(filePath)[0]
    
    # 获取最后一个斜杠位置
    
    index = name.rfind('/')
    
    # 找不到则返回 -1
    
    if index != -1:
        # 截取斜杠后面到结尾内容
        name = name[index+1:]
    
    # print name
    
    return name
  • 获取文件所在的目录名称作为页签值:

    与获取博客名称思路略有相似,获取最后一个斜杠位置,截掉斜杠之后的内容,在获取一个最后一个斜杠位置,假如有则截取斜杠之后的内容即是文件所在目录的名称:

    
    # 获得分类文件目录名称
    
    def getTypeNameByPath(filePath):
    fileTag = ''
    
    # 获取最后一个斜杠位置
    
    index = filePath.rfind('/')
    
    # 找不到则返回 -1
    
    if index != -1:
        # 截取斜杠后面到结尾内容
        fileTag = filePath[:index]
        # 截掉前面部分
        index = fileTag.rfind('/')
        if index != -1:
            fileTag = fileTag[index+1:]
    
    # print fileTag
    
    return fileTag
  • 向文件中插入内容:

    调用以上方法即可分别得到我们想要的信息:

    
    # 指定目录
    
    path = './'
    
    # 得到文件列表
    
    files = getFileList(path,'.md')   
    for i in files:
    print 'title: '+getFileSimpleName((i.decode("string_escape")))
    print 'date: '+get_FileCreateTime((path+i.decode("string_escape")))
    print 'tags: ['+getTypeNameByPath((i.decode("string_escape")))+']'

    接下来要做的就是把这些内容按照格式插入到文件中去,当然插入之前需要先检查文件中是否已经插入过类似的内容了,可以简单地通过检查开头 40 个字符串中是否包含这个字符串来判别:

    '''---
    title: '''
    • 1
    • 2

    关于展示分隔符 <!--more--> 插入的位置,大致逻辑是:第一个标题后面,而且刚好插入在第二个标题之前即可,而使用 Markdown 语法撰写的博客标题使用 # 来表示的,最终的插入方法如下:

    
    # 向文件中插入指定数据
    
    def addHeadToFile(filePath,title,date,tags):
    file = open(filePath,"r")
    content = file.read()
    index = content[:40].find('''---
    title:''')
    
    # 添加
    
    if index == -1:
        print 'Undadded'
        addContent = '''---
    title: '''+title+'''
    date: '''+date+'''
    tags: ['''+tags+''']
    categories: '''+tags+'''
    <hr />
    
    '''
        # 检测是否插入部分显示标签
        content = addContent + content
        index = content.find('''<!--more--> ''')
        if index == -1:
            # 获取第一段的位置
            index = content.find('''### ''')
            if index != -1:
                #print "first ### pos = ",index
                # 下一个标题位置(在第二个标题之前插入即可)
                pos = content[index:].find('''
    
    
    #''',1)
    
                if pos != -1:
                    index += pos
                    #print "second enter pos = ",index
                    content = content[:index]+'''
    <!--more-->
    '''+content[index:]
        file = open(filePath,"w")
        file.write(content)
    else:
        #print 'file head had added'
    
    # 记得要关闭文件
    
    file.close()

    最后完整的调用过程:

    
    # 指定目录
    
    path = './'
    
    # 得到文件列表
    
    files = getFileList(path,'.md')   
    
    # 声明一些全局变量
    
    title = ''
    date = ''
    tags = ''
    for i in files:
        title = getFileSimpleName(i.decode("string_escape"))
        date = get_FileCreateTime(path+i.decode("string_escape"))
        tags = getTypeNameByPath(i.decode("string_escape"))
        print 'title: '+title
        print 'date: '+date
        print 'tags: ['+tags+']'
        addHeadToFile(path+i.decode("string_escape"),title,date,tags)

其他:

如果你跟我一样出现了打印中文文件名变成诸如: “BATCH\xc5\xfa\xb4\xa6\xc0\xed\xbc\xf2\xbc\xc7.md” 这种格式的话,可以参考:Linux 下Python2.7解决list打印中文字符问题

本文转载自:

Yomut
粉丝 19
博文 191
码字总数 167789
作品 0
厦门
后端工程师
私信 提问
Python在DevOps中的应用

互联网时代,只有能够快速试验新想法,并在第一时间,安全、可靠的交付业务价值,才能保持竞争力。DevOps推崇的自动化构建/测试/部署,以及系统度量等技术实践,是互联网时代必不可少的。 大...

抚琴煮酒
2018/08/10
0
0
书籍:掌握Python脚本系统管理 Mastering Python Scripting for System Administrators - 2019.pdf

简介 主要特点 了解如何解决系统管理员的问题并自动执行日常活动 学习处理正则表达式,网络管理 构建GUI,网络抓取和数据库管理,包括数据分析 Python随着时间的推移不断发展,并扩展了与每个...

python人工智能命理
04/08
0
0
python 编写自动化小工具 未完成

python 编写自动化小工具 Python split() python数据类型之间的转换 str(demo) python换行写入文件 !/usr/bin/env python ecoding=utf-8 f=open(r"D:opsdevolduseroldused.txt","a+") newlin......

iOS_愛OS
2018/06/21
0
0
python大法之一-python是什么,及安装

个人独立博客http://www.xbman.cn 出处:http://www.xbman.cn/article/2 常言说得好会一技走遍天下。今天开始记录分享一下python的相关知识,算是对自己学习的总结。 第一篇 python是什么,及...

魏昊晅
2018/06/29
0
0
从0到1的逆袭之路,Python改变你的学习方式

  随着机器学习的兴起,Python 逐步成为了「最受欢迎」的语言。它简单易用、逻辑明确并拥有海量的扩展包,因此其不仅成为机器学习与数据科学的首选语言,同时在网页、数据爬取可科学研究等...

北北北乐
2018/08/22
0
0

没有更多内容

加载失败,请刷新页面

加载更多

JavaScript设计模式——适配器模式

  适配器模式是设计模式行为型模式中的一种模式;   定义:   适配器用来解决两个已有接口之间不匹配的问题,它并不需要考虑接口是如何实现,也不用考虑将来该如何修改;适配器不需要修...

有梦想的咸鱼前端
12分钟前
1
0
Andorid SQLite数据库开发基础教程(1)

Andorid SQLite数据库开发基础教程(1) Android数据库访问方式 SQLite是Android系统默认支持的文件数据库。该数据库支持SQL语言,适合开发人员上手。本教程将讲解如何开发使用SQLite的Andro...

大学霸
15分钟前
1
0
Handler简解

Handler 这里简化一下代码 以便理解 Handler不一定要在主线程建 但如Handler handler = new Handler(); 会使用当前的Looper的, 由于要更新UI 所以最好在主线程 new Handler() { mLooper = Lo...

shzwork
37分钟前
4
0
h5获取摄像头拍照功能

完整代码展示: <!DOCTYPE html> <head> <title>HTML5 GetUserMedia Demo</title> <meta charset="utf-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum......

诗书易经
40分钟前
3
0
正向代理和反向代理

文章来源 运维公会:正向代理和反向代理 1、正向代理 (1)服务对象不同 正向代理服务器的服务对象是客户端,可以将客户端和代理服务器看作一个整体。 (2)配置方法不同 需要在客户端配置代...

运维团
56分钟前
4
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部