logging模块
import logging logging.basicConfig(level=logging.DEBUG, format='%(asctime)s %(lineno)d %(levelname)s %(message)s', datefmt='%Y-%m-%d %X', filename='log.txt', filemode='w') logging.debug('debug message')logging.info('info message')logging.warning('warning message')logging.error('error message')logging.critical('critical message')
loggin模块参数
logging.basicConfig()函数中可通过具体参数来更改logging模块默认行为,可用参数有: filename:用指定的文件名创建FiledHandler,这样日志会被存储在指定的文件中。 filemode:文件打开方式,在指定了filename时使用这个参数,默认值为“a”还可指定为“w”。 format:指定handler使用的日志显示格式。 datefmt:指定日期时间格式。 level:设置rootlogger(后边会讲解具体概念)的日志级别 stream:用指定的stream创建StreamHandler。可以指定输出到sys.stderr,sys.stdout或者文件(f=open(‘test.log’,’w’)), 默认为sys.stderr。若同时列出了filename和stream两个参数,则stream参数会被忽略。 format参数中可能用到的格式化串: %(name)s Logger的名字 %(levelno)s 数字形式的日志级别 %(levelname)s 文本形式的日志级别 %(pathname)s 调用日志输出函数的模块的完整路径名,可能没有 %(filename)s 调用日志输出函数的模块的文件名 %(module)s 调用日志输出函数的模块名 %(funcName)s 调用日志输出函数的函数名 %(lineno)d 调用日志输出函数的语句所在的代码行 %(created)f 当前时间,用UNIX标准的表示时间的浮 点数表示 %(relativeCreated)d 输出日志信息时的,自Logger创建以 来的毫秒数 %(asctime)s 字符串形式的当前时间。默认格式是 “2003-07-08 16:49:45,896”。逗号后面的是毫秒 %(thread)d 线程ID。可能没有 %(threadName)s 线程名。可能没有 %(process)d 进程ID。可能没有 %(message)s用户输出的消息
简单使用logging
li = ['alex','wusir']your_input = input("请输入您的名字:")if your_input not in li and your_input.isalpha(): print('欢迎!') logging.info(your_input)elif your_input.isdigit(): print('请正确输入!') logging.error('用户输入的格式不对!')elif your_input in li: print('领导来了') logging.warning('赶快工作吧,别泡吧了')else: print('程序有bug了,赶快加班吧!') logging.critical('程序有bug了,赶快加班吧!')
paramiko模块
1. 介绍:
paramiko是一个用于做远程控制的模块,使用该模块可以对远程服务器进行命令或文件操作,值得一说的是,fabric和ansible内部的远程管理就是使用的paramiko来现实。
2. 下载安装
pip3 install paramiko #在python3中
pycrypto,由于 paramiko 模块内部依赖pycrypto,所以先下载安装pycrypto #在python2中pip3 install pycryptopip3 install paramiko注:如果在安装pycrypto2.0.1时发生如下错误 command 'gcc' failed with exit status 1...可能是缺少python-dev安装包导致如果gcc没有安装,请事先安装gcc
3. 使用
SSHClient
用于连接远程服务器并执行基本命令
基于用户名密码连接:
import paramiko# 创建SSH对象ssh = paramiko.SSHClient()# 允许连接不在know_hosts文件中的主机ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())# 连接服务器ssh.connect(hostname='39.106.144.72', port=22, username='root', password='xxx')# 执行命令stdin, stdout, stderr = ssh.exec_command('df')# 获取命令结果result = stdout.read()print(result.decode('utf-8'))# 关闭连接ssh.close()
SSHClient 封装 Transport
import paramikotransport = paramiko.Transport(('39.106.144.72', 22))transport.connect(username='root', password='xxx')ssh = paramiko.SSHClient()ssh._transport = transportstdin, stdout, stderr = ssh.exec_command('df')res=stdout.read()print(res.decode('utf-8'))transport.close()
基于公钥密钥连接:
客户端文件名:id_rsa
服务端必须有文件名:authorized_keys(在用ssh-keygen时,必须制作一个authorized_keys,可以用ssh-copy-id来制作)
import paramikoprivate_key = paramiko.RSAKey.from_private_key_file('/tmp/id_rsa')# 创建SSH对象ssh = paramiko.SSHClient()# 允许连接不在know_hosts文件中的主机ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())# 连接服务器ssh.connect(hostname='39.106.144.72', port=22, username='root', pkey=private_key)# 执行命令stdin, stdout, stderr = ssh.exec_command('df')# 获取命令结果result = stdout.read()print(result.decode('utf-8'))# 关闭连接ssh.close()
SFTPClient
用于连接远程服务器并执行上传下载
基于用户名密码上传下载
import paramiko transport = paramiko.Transport(('39.106.144.72',22))transport.connect(username='root',password='xxx') sftp = paramiko.SFTPClient.from_transport(transport)# 将location.py 上传至服务器 /tmp/test.pysftp.put('/tmp/id_rsa', '/etc/test.rsa')# 将remove_path 下载到本地 local_pathsftp.get('remove_path', 'local_path') transport.close()
基于公钥密钥上传下载
import paramikoprivate_key = paramiko.RSAKey.from_private_key_file('/tmp/id_rsa')transport = paramiko.Transport(('39.106.144.72', 22))transport.connect(username='root', pkey=private_key )sftp = paramiko.SFTPClient.from_transport(transport)# 将location.py 上传至服务器 /tmp/test.pysftp.put('/tmp/id_rsa', '/tmp/a.txt')# 将remove_path 下载到本地 local_pathsftp.get('remove_path', 'local_path')transport.close()
函数
在学习函数之前,一直遵循:面向过程编程,即:根据业务逻辑从上到下实现功能,其往往用一长段代码来实现指定功能,开发过程中最常见的操作就是粘贴复制,也就是将之前实现的代码块复制到现需功能处,如下
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | while True : if cpu利用率 > 90 % : #发送邮件提醒 连接邮箱服务器 发送邮件 关闭连接 if 硬盘使用空间 > 90 % : #发送邮件提醒 连接邮箱服务器 发送邮件 关闭连接 if 内存占用 > 80 % : #发送邮件提醒 连接邮箱服务器 发送邮件 关闭连接 |
腚眼一看上述代码,if条件语句下的内容可以被提取出来公用,如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | def 发送邮件(内容) #发送邮件提醒 连接邮箱服务器 发送邮件 关闭连接 while True : if cpu利用率 > 90 % : 发送邮件( 'CPU报警' ) if 硬盘使用空间 > 90 % : 发送邮件( '硬盘报警' ) if 内存占用 > 80 % : |
对于上述的两种实现方式,第二次必然比第一次的重用性和可读性要好,其实这就是函数式编程和面向过程编程的区别:
- 函数式:将某功能代码封装到函数中,日后便无需重复编写,仅调用函数即可
- 面向对象:对函数进行分类和封装,让开发“更快更好更强...”
函数式编程最重要的是增强代码的重用性和可读性
二、 函数的定义和使用
1 2 3 4 5 | def 函数名(参数): ... 函数体 ... |
函数的定义主要有如下要点:
- def:表示函数的关键字
- 函数名:函数的名称,日后根据函数名调用函数
- 函数体:函数中进行一系列的逻辑计算,如:发送邮件、计算出 [11,22,38,888,2]中的最大数等...
- 参数:为函数体提供数据
- 返回值:当函数执行完毕后,可以给调用者返回数据。
以上要点中,比较重要有参数和返回值:
1、返回值
函数是一个功能块,该功能到底执行成功与否,需要通过返回值来告知调用者。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | def 发送短信(): 发送短信的代码... if 发送成功: return True else : return False while True : # 每次执行发送短信函数,都会将返回值自动赋值给result # 之后,可以根据result来写日志,或重发等操作 result = 发送短信() if result = = False : 记录日志,短信发送失败... |
2、参数
为什么要有参数?
无参数
def CPU报警邮件() #发送邮件提醒 连接邮箱服务器 发送邮件 关闭连接def 硬盘报警邮件() #发送邮件提醒 连接邮箱服务器 发送邮件 关闭连接def 内存报警邮件() #发送邮件提醒 连接邮箱服务器 发送邮件 关闭连接 while True: if cpu利用率 > 90%: CPU报警邮件() if 硬盘使用空间 > 90%: 硬盘报警邮件() if 内存占用 > 80%: 内存报警邮件()
有参数
def 发送邮件(邮件内容) #发送邮件提醒 连接邮箱服务器 发送邮件 关闭连接 while True: if cpu利用率 > 90%: 发送邮件("CPU报警了。") if 硬盘使用空间 > 90%: 发送邮件("硬盘报警了。") if 内存占用 > 80%: 发送邮件("内存报警了。")
函数的有三中不同的参数:
- 普通参数
- 默认参数
- 动态参数
普通参数
# ######### 定义函数 ######### # name 叫做函数func的形式参数,简称:形参def func(name): print name# ######### 执行函数 ######### # 'guobaoyuan' 叫做函数func的实际参数,简称:实参func('guobaoyuan')
默认参数
def func(name, age = 18): print "%s:%s" %(name,age)# 指定参数func('guobaoyuan', 19)# 使用默认参数func('alex')注:默认参数需要放在参数列表最后
动态参数一
def func(*args): print args# 执行方式一func(11,33,4,4454,5)# 执行方式二li = [11,2,2,3,3,4,54]func(*li)
动态参数二
def func(**kwargs): print args# 执行方式一func(name='guobaoyuan',age=18)# 执行方式二li = {'name':'guobaoyuan', age:18, 'gender':'male'}func(**li)
动态参数三
def func(*args, **kwargs): print args print kwargs
发送邮件实例
import smtplibfrom email.mime.text import MIMETextfrom email.utils import formataddrmsg = MIMEText('邮件内容', 'plain', 'utf-8')msg['From'] = formataddr(["郭宝元", '932023756@qq.com'])msg['To'] = formataddr(["走人", '404042726@qq.com'])msg['Subject'] = "主题"server = smtplib.SMTP_SSL("smtp.qq.com")server.login("932023756", "邮箱密码")server.sendmail('932023756@qq.com', ['404042726@qq.com', ], msg.as_string())server.quit()print('发送成功!')