自动化运维Python系列(五)之常用模块

模块

用一坨代码实现了某个功能的代码集合

模块分为三种

· 自定义模块

· 第三方模块

· 内置模块

1)自定义模块

自己编写并存在在某个路径下的python程序,实现了某个功能,可以被其他程序调用

2)第三方模块

网络上下载并能兼容当前Python版本的第三方程序模块,比如支持HTTP测试的requests库

3)内置模块

C:\Python3.5\Lib目录下的py文件大部分都是Python的内置模块,如sys、os、time等

导入模块

import module
from module.xx.xx import xx
from module.xx.xx import xx as rename  
from module.xx.xx import *

模块默认搜索路径

import sys
 
for item in sys.path:  # python系统路径
    print(item)
输出:
C:\Python3.5\python.exe C:/software/github/Python/day5/s2.py
C:\software\github\Python\day5
C:\Users\lilongzi\PycharmProjects\Python
C:\software\github\Python
C:\Python3.5\python35.zip
C:\Python3.5\DLLs
C:\Python3.5\lib
C:\Python3.5
C:\Python3.5\lib\site-packages
C:\Python3.5\lib\site-packages\setuptools-27.2.0-py3.5.egg
 
sys.path.append(‘E:\\‘)  # 添加系统路径

Python常用模块

1)序列化相关 json pickle (序列化是指将)

序列化是指将一个字符串转换成基础数据类型或者基础数据类型数据转换成字符串

json 用于【字符串】 和 【python基础数据类型】间进行转换

pickle 用于【python特有类型】 和 【python基础数据类型】间进行转换

json 和 pickle 都提供了四个功能: dumps、dump、loads、load

import json
 
dic = {‘k1‘: ‘v1‘}
result = json.dumps(dic)  # 序列化 将python的基础数据类型转化成字符串形式
print(result, type(result))
 
s1 = ‘{"k1": 123}‘
dic1 = json.loads(s1)  # 反序列化 将字符串类型转换成python数据类型
print(s1, type(dic1))
 
输出
{"k1": "v1"} <class ‘str‘>
{"k1": 123} <class ‘dict‘>

dump和load

json.dump(dic, open(‘test‘, ‘w‘)) # 序列化之前,写入一个文件
 
result = json.load(open(‘test‘, ‘r‘)) # 读文件,再操作序列化
 
print(result, type(result))
 
输出
{‘k1‘: ‘v1‘} <class ‘dict‘>

json配合第三方requests模块获取天气API示例

import requests
 
import json
 
response = requests.get(‘http://wthrcdn.etouch.cn/weather_mini?city=上海‘)
response.encoding = ‘utf-8‘
 
dic = json.loads(response.text)
print(dic, type(dic))
 
输出
{‘status‘: 1000, ‘desc‘: ‘OK‘, ‘data‘: {‘yesterday‘: {‘low‘: ‘低温 19℃‘, ‘fx‘: ‘东北风‘, 
‘high‘: ‘高温 21℃‘, ‘date‘: ‘26日星期三‘, ‘fl‘: ‘3-4级‘, ‘type‘: ‘大雨‘}}...<class ‘dict‘>

pickle

import pickle
 
# pickle 只能Python识别 不适用于别的语言
li = [11, 22, 33]
r = pickle.dumps(li)
print(r)
 
result = pickle.loads(r)
print(result)
 
输出:
b‘\x80\x03]q\x00(K\x0bK\x16K!e.‘ # 转换成了只有Python自己能识别的代码
[11, 22, 33]

json/pickle 区别

# json更加适合跨语言 字符串 基本数据类
# pickle 处理Python复杂类型的序列化 缺点是仅适用于Python

注意,单引号和双引号在反序列化中的差别

import json
  
li = ‘["kobe", "jordan"]‘  #  正确写法
#li = "[‘kobe‘, ‘jordan‘]" #  错误写法
ret = json.loads(li)
print(ret, type(ret))
 
输出
[‘kobe‘, ‘jordan‘] <class ‘list‘>

2)time模块

时间有三种表现形式

print(time.time())  # 时间戳
print(time.strftime(‘%Y-%m-%d‘))  # 格式化的字符串 
print(time.localtime())  # 结构化时间
 
输出
1477623310.350726
2016-10-28
time.struct_time(tm_year=2016, tm_mon=10, tm_mday=28, tm_hour=10, tm_min=55, 
tm_sec=10, tm_wday=4, tm_yday=302, tm_isdst=0)

常见time操作

import time
 
print(time.ctime())
print(time.ctime(time.time()-86400))
 
# 输出
# Fri Oct 28 11:06:30 2016
# Thu Oct 27 11:06:30 2016
print(time.gmtime())
time_obj = time.gmtime()
print(time_obj.tm_year, time_obj.tm_mon, time_obj.tm_mday)
print(time.mktime(time_obj))
 
# 输出
# time.struct_time(tm_year=2016, tm_mon=10, tm_mday=28, tm_hour=3, tm_min=12, tm_sec=44, 
# tm_wday=4, tm_yday=302, tm_isdst=0)
# 2016 10 28
# 1477595761.0
 
# 将struct_time格式转换成指定格式
print(time.localtime())
print(time.strftime("%Y-%m-%d %H:%S", time.localtime()))
# 与strftime相反 将字符串转换成strcut格式
tm = time.strptime("2016-10-10 10:50", "%Y-%m-%d %H:%M")
print(tm)
 
# 输出
# time.struct_time(tm_year=2016, tm_mon=10, tm_mday=28, tm_hour=11, tm_min=17, 
# tm_sec=30, tm_wday=4, tm_yday=302, tm_isdst=0)
# 2016-10-28 11:30
# time.struct_time(tm_year=2016, tm_mon=10, tm_mday=10, tm_hour=10, tm_min=50, 
# tm_sec=0, tm_wday=0, tm_yday=284, tm_isdst=-1)
 
import datetime
print(datetime.datetime.now())  # 显示当前时间
print(datetime.date.today())
print(datetime.date.fromtimestamp(time.time()-86400))  # 将时间戳转换成格式化日期
 
# 时间加减
print(datetime.datetime.now() + datetime.timedelta(days=10))  # 比现在加10天
print(datetime.datetime.now() - datetime.timedelta(days=10))  # 比现在晚10天
print(datetime.datetime.now() + datetime.timedelta(hours=10))  # 加10小时
current_time = datetime.datetime.now()
print(current_time.replace(2015, 10, 10))  # 直接替换时间
print(datetime.datetime.strptime("09/10/15 11:40", "%d/%m/%y %H:%M"))
 
# 输出
# 2016-10-28 11:21:54.580869
# 2016-10-28
# 2016-10-27
# 2016-11-07 11:21:54.580869
# 2016-10-18 11:21:54.580869
# 2016-10-28 21:21:54.580869
# 2015-10-10 11:21:54.580869
# 2015-10-09 11:40:00

时间转换图

格式样式

    %Y  Year with century as a decimal number.
    %m  Month as a decimal number [01,12].
    %d  Day of the month as a decimal number [01,31].
    %H  Hour (24-hour clock) as a decimal number [00,23].
    %M  Minute as a decimal number [00,59].
    %S  Second as a decimal number [00,61].
    %z  Time zone offset from UTC.
    %a  Locale‘s abbreviated weekday name.
    %A  Locale‘s full weekday name.
    %b  Locale‘s abbreviated month name.
    %B  Locale‘s full month name.
    %c  Locale‘s appropriate date and time representation.
    %I  Hour (12-hour clock) as a decimal number [01,12].
    %p  Locale‘s equivalent of either AM or PM.

3)logging模块

用于便捷记录日志和线程安全的模块

import logging
 
# 设置输出文件、文件格式和日志级别
logging.basicConfig(filename=‘example.log‘, level=logging.INFO,
                    format=‘%(asctime)s %(message)s‘, datefmt=‘%m/%d/%Y %I:%M:%S %p‘)
                     
# 开始打印日志信息
logging.debug(‘This message should go to the log file‘)
logging.info(‘So should this‘)
logging.warning(‘And this, too‘)
logging.warning("user [kobe] attempted wrong password more than 3 times")
logging.critical("Server is down...")
 
# 输出
example.log>>
10/28/2016 01:12:14 PM So should this
10/28/2016 01:12:14 PM And this, too
10/28/2016 01:12:14 PM user [kobe] attempted wrong password more than 3 times
10/28/2016 01:12:14 PM Server is down...

日志等级

CRITICAL = 50
FATAL = CRITICAL
ERROR = 40
WARNING = 30
WARN = WARNING
INFO = 20
DEBUG = 10
NOTSET = 0

日志记录格式

多文件记录日志

# 1、创建logger 谁去发日志
logger = logging.getLogger(‘TEST-LOG‘)  # 先获取logger对象
logger.setLevel(logging.DEBUG)  # 设置全局日志级别
 
# 2、创建Handler 发给屏幕
ch = logging.StreamHandler()  # 在屏幕上打印
ch.setLevel(logging.DEBUG)  # 设置在屏幕上打印日志的全局级别
 
# 3、创建Handler 文件
fh = logging.FileHandler("access.log")
fh.setLevel(logging.WARNING)  # 日志局部级别
fh_err = logging.FileHandler("error.log")
fh_err.setLevel(logging.ERROR)
 
# 4、创建formatter输出格式
formatter = logging.Formatter(‘%(asctime)s - %(name)s - %(levelname)s - %(message)s‘)
formatter_for_file = logging.Formatter(‘%(asctime)s - %(filename)s - %(levelname)s - %(message)s‘)
 
# 5、分别设置格式
ch.setFormatter(formatter)
fh.setFormatter(formatter_for_file)
fh_err.setFormatter(formatter)
  
# 6、向logger注册
logger.addHandler(ch)
logger.addHandler(fh)
logger.addHandler(fh_err)
  
# 7、打印
logger.debug(‘debug message‘)
logger.info(‘info message‘)
logger.warn(‘warn message‘)
logger.error(‘error message‘)
logger.critical(‘critical message‘)
 
屏幕输出:
2016-10-28 13:20:13,656 - TEST-LOG - DEBUG - debug message
2016-10-28 13:20:13,656 - TEST-LOG - INFO - info message
2016-10-28 13:20:13,656 - TEST-LOG - WARNING - warn message
2016-10-28 13:20:13,656 - TEST-LOG - ERROR - error message
2016-10-28 13:20:13,657 - TEST-LOG - CRITICAL - critical message
文件输出:
access.log>>
2016-10-28 13:20:13,656 - log.py - WARNING - warn message
2016-10-28 13:20:13,656 - log.py - ERROR - error message
2016-10-28 13:20:13,657 - log.py - CRITICAL - critical message
error.log>>
2016-10-28 13:20:13,656 - TEST-LOG - ERROR - error message
2016-10-28 13:20:13,657 - TEST-LOG - CRITICAL - critical message

4)sys

用于对Python解释器相关操作:

sys.argv           命令行参数List,第一个元素是程序本身路径

sys.exit(n)        退出程序,正常退出时exit(0)

sys.version        获取Python解释程序的版本信息

sys.maxint         最大的Int

sys.path           返回模块的搜索路径,初始化时使用PYTHONPATH环境变量的值

sys.platform       返回操作系统平台名称

sys.stdin          输入相关

sys.stdout         输出相关

sys.stderror       错误相关

关于sys运用:进度条

def view_bar(num, total):
    rate = num / total
    rate_num = int(rate * 100)
    r1 = ‘\r%s>%d%%‘ % ("="*num, rate_num,)  # 加 r 的话让每次输出回到初始最前面位置
    sys.stdout.write(r1)  # 和print的区别就是不加换行符
    sys.stdout.flush()  # 清空屏幕输出
 
for i in range(0, 101):
    time.sleep(0.1)
    view_bar(i, 100)

5)os

系统级别的操作

os.getcwd()                 获取当前工作目录,即当前python脚本工作的目录路径

os.chdir("dirname")         改变当前脚本工作目录;相当于shell下cd

os.curdir                   返回当前目录: (‘.‘)

os.pardir                   获取当前目录的父目录字符串名:(‘..‘)

os.makedirs(‘dir1/dir2‘)    可生成多层递归目录

os.removedirs(‘dirname1‘)   若目录为空,则删除,并递归到上一级目录,如若也为空,则删除,依此类推

os.mkdir(‘dirname‘)         生成单级目录;相当于shell中mkdir dirname

os.rmdir(‘dirname‘)         删除单级空目录,若目录不为空则无法删除,报错;相当于shell中rmdir dirname

os.listdir(‘dirname‘)       列出指定目录下的所有文件和子目录,包括隐藏文件,并以列表方式打印

os.remove()                 删除一个文件

os.rename("oldname","new")  重命名文件/目录

os.stat(‘path/filename‘)    获取文件/目录信息

os.sep                      操作系统特定的路径分隔符,win下为"\\",Linux下为"/"

os.linesep                  当前平台使用的行终止符,win下为"\t\n",Linux下为"\n"

os.pathsep                  用于分割文件路径的字符串

os.name                     字符串指示当前使用平台。win->‘nt‘; Linux->‘posix‘

os.system("bash command")   运行shell命令,直接显示

os.environ                  获取系统环境变量

os.path.abspath(path)       返回path规范化的绝对路径

os.path.split(path)         将path分割成目录和文件名二元组返回

os.path.dirname(path)       返回path的目录。其实就是os.path.split(path)的第一个元素

os.path.basename(path)      返回path最后的文件名。如何path以/或\结尾,那么就会返回空值。即os.path.split(path)的第二个元素

os.path.exists(path)        如果path存在,返回True;如果path不存在,返回False

os.path.isabs(path)         如果path是绝对路径,返回True

os.path.isfile(path)        如果path是一个存在的文件,返回True。否则返回False

os.path.isdir(path)         如果path是一个存在的目录,则返回True。否则返回False

os.path.join(path1[, path2[, ...]])  将多个路径组合后返回,第一个绝对路径之前的参数将被忽略

os.path.getatime(path)      返回path所指向的文件或者目录的最后存取时间

os.path.getmtime(path)      返回path所指向的文件或者目录的最后修改时间

6)hashlib

# import hashlib
 
# obj = hashlib.md5(bytes(‘sdfsdfsadf‘, encoding=‘utf-8‘))  # 加bytes任意字符防止被撞库破译
# obj.update(bytes(‘123‘, encoding=‘utf-8‘))
# r = obj.hexdigest()
# print(r)
 
# python内置还有一个 hmac 模块,它内部对我们创建 key 和 内容 进行进一步的处理然后再加密
# import hmac 
 
# h = hmac.new(bytes(‘898oaFs09f‘,encoding="utf-8"))
# h.update(bytes(‘admin‘,encoding="utf-8"))
# print(h.hexdigest())

7)re

.  匹配除换行符以外的任意字符

\w 匹配字母或数字或下划线或汉字

\s 匹配任意的空白符 

\d 匹配数字

\b 匹配单词的开始或结束 

^  匹配字符串的开始

$  匹配字符串的结束 

*  重复零次或更多次

+  重复一次或更多次 

?  重复零次或一次

{n}   重复n次 

{n,}  重复n次或更多次

{n,m} 重复n到m次 

# import re
  
# match
# print(re.match(‘com‘, ‘comwww.runcombb‘).group())  # match 匹配起始位置
# print(re.search(‘com‘, ‘www.runcombb‘).group())  # search 匹配第一次位置
 
# sub subn 匹配 替换
# print(re.sub("g.t", "have", ‘I get A, get B‘, 1))  # 1表示只替换1次
# print(re.subn("g.t", "have", ‘I get A, get B‘))  # 提示替换了几次
 
# split
# print(re.split(‘\d+‘, ‘one1two2three3four4‘))  # 有空格
# 输出
# [‘one‘, ‘two‘, ‘three‘, ‘four‘, ‘‘]
 
# compile 封装一个固定匹配规则供多次调用
# s = "JGood is a boy,so cool..."
# r = re.compile(r‘\w*oo\w*‘)   # 查找所有包含oo的单词
# print(r.findall(s))
# 输出:
# [‘JGood‘, ‘cool‘]
 
# 反斜杠
# 在Python中 要进行两次转义才能匹配一个带反斜杠的字符 所以需要4个 \\\# print(re.search("\\\\com", "\comcn").group())
 
# 单词
# print(re.findall(r‘I\b‘, ‘I&am Ikobe‘)) # 有很多字符可以用来分隔单词 这里使用&
 
# 分组
# 去已经匹配到的数据中再提取数据
# origin = ‘has sdfsdfsdfwer432‘
# r = re.match("h\w+", origin)  # 输出:has () {}
# r = re.match("h(\w+)", origin)  # 输出:has (‘as‘,) {}
# r = re.match("h(?P<name>\w+)", origin)  # 输出:has (‘as‘,) {‘name‘: ‘as‘}
# print(r.group())
# print(r.groups())
# print(r.groupdict())
 
# findall 分组
# origin = "hasaabc halaaabc"
# r = re.findall("h(\w+)a(ab)c", origin)  # 首先整体匹配 再将分组放入结果
# print(r)
# 输出:
# [(‘as‘, ‘ab‘), (‘ala‘, ‘ab‘)]
 
# spilt 分组
# origin = "hello alex abc alex age"
# r = re.split("a(le)x", origin, 1)  # 忽略了alex 直接匹配le
# print(r)
# 输出:
# [‘hello ‘, ‘le‘, ‘ abc alex age‘]

常用正则表达式

# IP:
# ^(25[0-5]|2[0-4]\d|[0-1]?\d?\d)(\.(25[0-5]|2[0-4]\d|[0-1]?\d?\d)){3}$
 
# 手机号:
# ^1[3|4|5|8][0-9]\d{8}$
 
# 邮箱:
# [a-zA-Z0-9_-][email protected][a-zA-Z0-9_-]+(\.[a-zA-Z0-9_-]+)+

8)configparser

用于处理特定格式的文件 实质上是通过open来操作文件

源文件特定格式

[section1]
k1 = 123
k2 = v2
 
[section2]
k1 = 456
k2 = v2
k3 = v3

常见操作

import configparser
 
# 1、读取文件 读取节点
config = configparser.ConfigParser()
config.read(‘conf_file‘, encoding=‘utf-8‘)
ret = config.sections()  # 获取所有节点 返回一个列表
ret1 = config.items(‘section1‘)  # 读取节点下的键值对
ret2 = config.options(‘section1‘)  # 读取某个节点下的键
 
print(ret)
print(ret1)
print(ret2)
 
# 2、读取节点键值
v = config.get(‘section1‘, ‘k1‘)  # 获取指定key下的值 默认 str 类型
# v = config.getint(‘section1‘, ‘k1‘)
# v = config.getfloat(‘section1‘, ‘k1‘)
# v = config.getboolean(‘section1‘, ‘k1‘)
print(v, type(v))
 
# 3、检查 添加 删除节点
has_sec = config.has_section(‘section1‘)
print(has_sec)
 
# config.add_section(‘section5‘)
# config.write(open(‘conf_file‘, ‘w‘))
 
# config.remove_section(‘section3‘)
# config.write(open(‘conf_file‘, ‘w‘))
 
# 4、检查 删除 设置 指定组内的键值对
has_opt = config.has_option(‘section1‘, ‘k1‘)
print(has_opt)
 
# config.remove_option(‘section2‘, ‘k3‘)
# config.write(open(‘conf_file‘, ‘w‘))
 
config.set(‘section5‘, ‘k1‘, ‘123‘)
config.write(open(‘conf_file‘, ‘w‘))

9)xml

xml是实现不同语言和程序之间进行数据交换的协议

from xml.etree import ElementTree as ET
 
# xml有两个常见格式
# 1)直接读取字符串格式的xml
str_xml = open(‘xo.xml‘, ‘r‘).read()
root = ET.XML(str_xml)  # 这里没有建立 xml tree 所以不能直接将内存中的xml写回文件
 
# 2)读取xml格式文件
# tree = ET.parse(‘xo.xml‘)  # 首先建立了一个 xml tree 对象
# root = tree.getroot()
# print(root)  # 获取根节点
# print(root.tag)  # 取根节点名
# print(root.attrib)  # 获取节点属性
 
# 3) 遍历多层xml
for child in root:
    print(child.tag, child.attrib)
    for child_second in child:
        print(child_second.tag, child_second.text)  # child_second.text 节点内容
 
# 4) 遍历指定的节点
for node in root.iter(‘year‘):
    print(node.tag, node.text)
 
# 5) 修改节点内容
for node in root.iter(‘year‘):
    new_year = int(node.text) + 1
    node.text = str(new_year)
 
    node.set(‘name‘, ‘london‘)
    node.set(‘age‘, ‘18‘)
 
    del node.attrib[‘age‘]
 
tree = ET.ElementTree(root)
tree.write(‘new_xo.xml‘, encoding=‘utf-8‘)
  
# 6、删除节点
str_xml = open(‘xo.xml‘, ‘r‘).read()
root = ET.XML(str_xml)
for country in root.findall(‘country‘):
    rank = int(country.find(‘rank‘).text)
    if rank > 50:
        root.remove(country)
 
tree = ET.ElementTree(root)
tree.write(‘new_xoo.xml‘, encoding=‘utf-8‘)
 
# 7、创建 xml 文档
 
from xml.dom import minidom
 
 
def prettify(elem):
    """将节点转换成字符串,并添加缩进。
    """
    rough_string = ET.tostring(elem, ‘utf-8‘)
    reparsed = minidom.parseString(rough_string)
    return reparsed.toprettyxml(indent="\t")
 
# 创建根节点
root = ET.Element("famliy")
 
# 创建大儿子
# son1 = ET.Element(‘son‘, {‘name‘: ‘儿1‘})
son1 = root.makeelement(‘son‘, {‘name‘: ‘儿1‘})
# 创建小儿子
# son2 = ET.Element(‘son‘, {"name": ‘儿2‘})
son2 = root.makeelement(‘son‘, {"name": ‘儿2‘})
 
# 在大儿子中创建两个孙子
# grandson1 = ET.Element(‘grandson‘, {‘name‘: ‘儿11‘})
grandson1 = son1.makeelement(‘grandson‘, {‘name‘: ‘儿11‘})
# grandson2 = ET.Element(‘grandson‘, {‘name‘: ‘儿12‘})
grandson2 = son1.makeelement(‘grandson‘, {‘name‘: ‘儿12‘})
 
son1.append(grandson1)
son1.append(grandson2)
 
 
# 把儿子添加到根节点中
root.append(son1)
root.append(son1)
 
raw_str = prettify(root)  # 自动添加缩进
 
f = open("xxxoo.xml", ‘w‘, encoding=‘utf-8‘)
f.write(raw_str)
f.close()

10)shutil

用来处理 文件 文件夹 压缩包 的模块

import shutil
 
# 拷贝文件内容
shutil.copyfileobj(open(‘old.xml‘, ‘r‘), open(‘new.xml‘, ‘w‘))
 
# 拷贝文件
shutil.copyfile(‘f1.log‘, ‘f2.log‘)
 
# 拷贝权限
shutil.copymode(‘f1.log‘, ‘f2.log‘)
 
# 拷贝文件状态信息
shutil.copystat(‘f1.log‘, ‘f2.log‘)
 
# 拷贝文件和权限
shutil.copy(‘f1.log‘, ‘f2.log‘)
 
# 递归地拷贝文件夹
# shutil.copytree(‘folder1‘, ‘folder2‘,
ignore=shutil.ignore_patterns(‘*.pyc‘, ‘*.txt‘))
 
# 递归地删除文件
# shutil.rmtree(‘folder2‘)
 
# 递归地移动重命名文件
# shutil.move(‘folder2‘, ‘folder3‘)
 
# 打包文件
ret = shutil.make_archive(r‘C:\GitHub\Python\day7\shutil\www‘, ‘gztar‘,
root_dir=r‘C:\GitHub\Python\day7\shutil\folder1‘)

zipfile tarfile

import zipfile
 
# 压缩
z = zipfile.ZipFile(‘z.zip‘, ‘w‘)
z.write(‘xo.xml‘)
z.write(‘xxxoo.xml‘)
z.close()
 
# 解压
z = zipfile.ZipFile(‘z.zip‘, ‘r‘)
for item in z.namelist():
    print(item)
# z.extractall()
z.extract(‘xo.xml‘)
 
import tarfile
 
# 压缩
tar = tarfile.open(‘z.tar‘, ‘w‘)
tar.add(‘xo.xml‘, arcname=‘bbs2.log‘)
tar.add(‘xxxoo.xml‘, arcname=‘cmdb.log‘)
tar.close()
 
# 解压
tar = tarfile.open(‘z.tar‘, ‘r‘)
# for item in tar.getmembers():
#     print(item, type(item))
obj = tar.getmember(‘cmdb.log‘)  # 和zipfile不同的是 再解压特定文件前要先获取文件特殊对象值
tar.extract(obj)
tar.close()

11)系统命令

和处理shell相关的命令

import subprocess
 
# 返回命令执行结果
# result = subprocess.call(‘ls -l‘, shell=True)
# result = subprocess.call([‘ls‘, ‘-l‘], shell=False)
# print(result)
 
# subprocess.check_call(["ls", "-l"])
# subprocess.check_call("exit 1", shell=True)
 
# 好像没Python废弃了
subprocess.check_output(["echo", "Hello World!"], shell=False)
subprocess.check_output("exit 1", shell=True)
 
# 2、执行复杂的系统相关命令
 
# 1)切换目录再执行命令
obj = subprocess.Popen("mkdir t3", shell=True, cwd=‘/home/dev‘,)
 
# 2)有多行且复杂的命令使用三个接口
# obj = subprocess.Popen(["python"], stdin=subprocess.PIPE, 
stdout=subprocess.PIPE, stderr=subprocess.PIPE, universal_newlines=True)
# obj.stdin.write("print(1)\n")  # 传命令接口
# obj.stdin.write("print(2)")
# obj.stdin.close()
# 
# cmd_out = obj.stdout.read()  # 读接口
# obj.stdout.close()
# cmd_error = obj.stderr.read()  # 读错误接口
# obj.stderr.close()
# 
# print(cmd_out)
# print(cmd_error)
 
# 3)一次读输出
# obj = subprocess.Popen(["python"], stdin=subprocess.PIPE, 
stdout=subprocess.PIPE, stderr=subprocess.PIPE, universal_newlines=True)
# obj.stdin.write("print(1)\n")
# obj.stdin.write("print(2)")
#
# out_error_list = obj.communicate()
# print(out_error_list)
 
# 4)简单写法
# obj = subprocess.Popen(["python"], stdin=subprocess.PIPE,
stdout=subprocess.PIPE, stderr=subprocess.PIPE, universal_newlines=True)
# out_error_list = obj.communicate(‘print("hello")‘)
# print(out_error_list)
时间: 2024-07-30 10:59:31

自动化运维Python系列(五)之常用模块的相关文章

自动化运维Python系列(一)之基础篇

Python介绍 Python是由创始人吉多·范罗苏姆(Guido van Rossum)在1989年圣诞节假期期间,为了打发时间,构思出来的一个新的脚本解释器.由于Guido在开发Python语言过程中,借鉴了很多ABC语言特性,所有后来包括Guido自己也那么认为,Python语言的前身就是ABC语言. Python是一门面向对象的.动态解释型强定义语言:Python崇尚简洁.优美.清晰,是一门优秀的被广泛使用的语言. 在2015年以前,最流行的Python版本还是2.4,但是由于Pytho

自动化运维Python系列之ForeignKey、relationship联表查询

一对多和多对多 数据库表结构设计是程序项目开发前的重要环节,后期数据库操作都是围绕着这个已经设计好的表结构进行,如果表结构设计有问题,整个程序项目就有存在需要整个推翻重构的风险... 数据库表结构除了简单的单表操作以外,还有一对多.多对多等. 一对多 基于SQLAlchemy我们可以先创建如下结构的2张表,然后来看看具体怎样通过外键ForeignKey或者relationship联表操作 创建表 from sqlalchemy.ext.declarative import declarative

Ansible 自动化运维工具之inventory和常用模块介绍

一.inventory介绍 前面我们介绍过ansible的hosts文件是存放被管理主机的,被管理主机比较少的情况下,直接在hosts中定义即可,但是以后很定会管理多台主机,而ansible可管理的主机集合就叫做inventory.在ansible中,描述你主机的默认方法是将它们列在一个文本文件中,这个文件叫inventory文件. 一个简单的inventory文件可能只包含一组主机名的列表,如下: ftp.testansible.com samba.testansible.com mail.t

自动化运维Python系列(七)之Socket编程

了解知识点TCP\IP 要想理解socket首先得熟悉一下TCP/IP协议族, TCP/IP(Transmission Control Protocol/Internet Protocol)即传输控制协议/网间协议,定义了主机如何连入因特网及数据如何再它们之间传输的标准, 从字面意思来看TCP/IP是TCP和IP协议的合称,但实际上TCP/IP协议是指因特网整个TCP/IP协议族.不同于ISO模型的七个分层,TCP/IP协议参考模型把所有的TCP/IP系列协议归类到四个抽象层中(数据链路层和物理

自动化运维Python系列之Memcache、Redis操作

Memcached Memcached 是一个高性能的分布式内存对象缓存系统,用于动态Web应用以减轻数据库负载.它通过在内存中缓存数据和对象来减少读取数据库的次数,从而提高动态.数据库驱动网站的速度.Memcached基于一个存储键/值对的hashmap.其守护进程(daemon )是用C写的,但是客户端可以用任何语言来编写,并通过memcached协议与守护进程通信. Memcached安装 wget http://memcached.org/latest tar -zxvf memcach

自动化运维Python系列(六)之面向对象

面向对象编程 面向过程:根据业务逻辑从上到下垒代码 函数式:将某功能代码封装到函数中,以后直接调用,不需要再次编写 面向对象:对函数进行分类和封装,让开发"更快更好更强..." # 像Java和C#等编程语言仅支持面向对象编程,而Python支持函数式编程和面向对象编程混用 面向对象示例 # 函数式编程 def bar():     print('bar')   bar()  # 直接调用函数 # 面向对象编程 class Foo:  # 创建类        def bar(self

自动化运维Python系列(四)之装饰器和生成器

装饰器 在理解什么事装饰器之前,我们需要理解:函数也是一个对象,可以赋值给变量,通过变量来调用 def f1():     print('2016') d = f1 d() 输出: 2016 那么装饰器的作用就是在不改变原函数的前提下,调用这些函数,并且为函数增加我们需要的新功能. 我们平时在编写好很多独立函数模块以后,突然需要在每个模块内添加一个功能,比如: def f1():     print('F1') def f2():     print('F2') def f3():     pr

自动化运维Python系列之Django进阶操作

FBV && CBV FBV.CBV是Django视图路由处理模型,当用户请求送达路由系统URL后,由其转发给视图view来分析并处理 // FBV    function base views  // CBV    class base views 区别就是一个直接用函数驱动,一个用类驱动,两者在使用上存在一些区别 1)FBV URL中根据路由匹配直接转发给视图中的某一个处理函数 urlpatterns = [     url(r'^home/', views.home), ] 视图函数

自动化运维Python系列之Django信号、缓存操作

Django信号 Django内部提供了一种"信号强度"处理机制,简单理解就是当Django在接收到请求后内部做某些特定操作前发出信号,提醒一些接受者或者做操作,这样的好处就是方便程序定制小功能插件,也是对本身框架的一种节藕操作 1)Django的内置信号 Model signals     pre_init                # django的modal执行其构造方法前,自动触发     post_init               # django的modal执行其构