python自动化运维之路04
装饰器
装饰器(decorator)是一种高级Python语法。装饰器可以对一个函数、方法或者类进行加工。
在Python中,我们有多种方法对函数和类进行加工,比如在Python闭包中,我们见到函数对象作为某一个函数的返回结果。
相对于其它方式,装饰器语法简单,代码可读性高。因此,装饰器在Python项目中有广泛的应用。
装饰器的应用场景:饰器是一个很著名的设计模式,经常被用于有切面需求的场景,较为经典的有插入日志、性能测试、事务处理等。装
饰器是解决这类问题的绝佳设计,有了装饰器,我们就可以抽离出大量函数中与函数功能本身无关的雷同代码并继续重用。
概括的讲,装饰器的作用就是为已经存在的对象添加额外的功能。
装饰器的规则:
- def derector(function):
- def wrapper(*args,**kwargs):
- function(*args,**kwargs)
- return wrapper
装饰器可以用def的形式定义,如上面代码中的decorator。装饰器接收一个可调用对象作为输入参数,并返回一个新的可调用对象。
装饰器新建了一个可调用对象,也就是上面的wrapper。
1.装饰器中如何传递参数?
- def outter1(Func):
- def wrapper(args):
- print("Before")
- Func(args)
- print("After")
- return wrapper
- @outter1
- def Function1(agrs):
- print("in the Function1:%s" %agrs)
- Function1("nihao")
2.要修饰的函数中有返回值如何处理?
- def outter2(Func):
- def wrapper():
- res = Func()
- return res
- return wrapper
- @outter2
- def Function2():
- print("in the Function2")
- return "Function2"
- print(Function2())
3.带有参数的装饰器
- import time
- user,passwd = "alex","abc123"
- def derector(auth_type):
- print("auth_type:%s" %auth_type)
- def outwrapper(function):
- def wrapper(*args,**kwargs):
- print(*args,**kwargs)
- if auth_type =="local":
- username = input("input your username:")
- password = input("input the password:")
- if username == user and password == passwd:
- print('\033[32;1mUser has passed authentication!\033[0m')
- res = function(*args, **kwargs)
- print("===========After Authtication=============")
- return res
- else:
- print("\033[32;1mInvalid User or Password\033[0m")
- elif auth_type == "ldap":
- print("gaomaoxian!")
- return wrapper
- return outwrapper
- @derector(auth_type="ldap")
- def bine():
- print("in the bin!")
- @derector(auth_type="local")
- def home():
- print("in the home!")
- return "from home!"
- def index():
- print("in the index")
- bine()
- home()
- index()
- #!/usr/bin/env python
- # _*_ encoding:utf-8 _*_
- # author:snate
- def Before(*agrs,**kwargs):
- print("before")
- def After(*args,**kwargs):
- print("after")
- def derector(before_Fuc,after_Fuc):
- def out_wrapper(main_fuc):
- def wrapper(*agrs,**kwargs):
- before_result = before_Fuc(*agrs,*kwargs)
- if before_result != None:
- return before_result
- index_result = main_fuc(*agrs, **kwargs)
- if index_result != None:
- return index_result
- after_result = after_Fuc(*agrs,**kwargs)
- if after_result != None:
- return after_result
- return wrapper
- return out_wrapper
- @derector(Before,After)
- def index(*agrs,**kwagrs):
- print("index")
- index(1,2)
2.生成器和迭代器
通过列表生成式,我们可以直接创建一个列表。但是,受到内存限制,列表容量肯定是有限的。
而且,创建一个包含100万个元素的列表,不仅占用很大的存储空间,如果我们仅仅需要访问前面几个元素,那后面绝大多数元素占用的空间都白白浪费了。
list = [x*x for x in range(10)]
print(list) # [0, 1, 4, 9, 16, 25, 36, 49, 64, 81]
list1 = (x*x for x in range(10))
print(list1)# <generator object <genexpr> at 0x0000000000B130F8>
只要把一个列表生成式的[]改成(),就创建了一个generator。
- list = [x*x for x in range(10)]
- print(list) # [0, 1, 4, 9, 16, 25, 36, 49, 64, 81]
- list1 = (x*x for x in range(10))
- print(list1)# <generator object <genexpr> at 0x0000000000B130F8>
只要把一个列表生成式的[]改成(),就创建了一个generator。
- print(list1.__next__()) # 0
- print(list1.__next__()) # 1
- print(list1.__next__()) # 4
- print(list1.__next__()) # 9
- print(list1.__next__()) # 16
- print(list1.__next__()) # 25
- print(list1.__next__()) # 36
- print(list1.__next__()) # 49
- print(list1.__next__()) # 64
- print(list1.__next__()) # 81
- print(list1.__next__()) # StopIteration,
generator保存的是算法,每次调用next(g),或者是g的__next__()私有方法,就计算出g的下一个元素的值,直到计算到最后一个元素,没有更多的元素时,抛出StopIteration的错误
yeild关键字
著名的斐波拉契数列(Fibonacci),除第一个和第二个数外,任意一个数都可由前两个数相加得到:
1, 1, 2, 3, 5, 8, 13, 21, 34, ...
- def fib(max):
- n,a,b = 0,0,1
- while n<max:
- yield b # 此处yield的作用是保存函数的执行状态,释放cpu等待状态,利用next唤醒程序。
- a,b = b,a+b
- n += 1
- return "nihao"
- g = fib(10)
- # for i in g:
- # print(i)
- while True:
- try:
- x = next(g)
- print("g:",x)
- except StopIteration as e:
- print("e.value:%s"%e.value)
- break
一个函数中如果有yield关键字,那个这个函数就不在是普通的函数,而是成了生成器。
生产者消费者模型:
- #!/usr/bin/env python
- # _*_ encoding:utf-8 _*_
- # author:snate
- import time
- def consumer(name):
- print("%s准备吃包子了!"%name)
- while True:
- baozi = yield
- print("%s吃了第%s个包子" %(name ,baozi))
- def producer(name):
- c1 = consumer("A")
- c2 = consumer("B")
- c1.__next__()
- c2.__next__()
- for i in range(10):
- print("%s 生产了两个包子" %name)
- time.sleep(1)
- c1.send(i)
- c2.send(i)
- producer("alex")
有yield函数式生成器,c1.__next__()是执行到yield的地方,然后跳出函数,然后执行for循环,当执行到c1.send(i),将函数从yield处唤醒,并且将i值传递给yield。
们已经知道,可以直接作用于for循环的数据类型有以下几种:
一类是集合数据类型,如list、tuple、dict、set、str等;
一类是generator,包括生成器和带yield的generator function。
这些可以直接作用于for循环的对象统称为可迭代对象:Iterable。
可以使用isinstance()判断一个对象是否是Iterable对象:
isinstance({},Iterable}
isinstance((),Iterable}
isinstance([],Iterable}
列表,元组、字典、生成器都是可迭代对象
可以被next()函数调用并不断返回下一个值的对象称为迭代器:Iterator。
可以使用isinstance()判断一个对象是否是Iterator对象:
生成器都是Iterator对象,但list、dict、str虽然是Iterable,却不是Iterator。
把list、dict、str等Iterable变成Iterator可以使用iter()函数
你可能会问,为什么list、dict、str等数据类型不是Iterator?
这是因为Python的Iterator对象表示的是一个数据流,Iterator对象可以被next()函数调用并不断返回下一个数据,直到没有数据时抛出StopIteration错误。
可以把这个数据流看做是一个有序序列,但我们却不能提前知道序列的长度,
只能不断通过next()函数实现按需计算下一个数据,所以Iterator的计算是惰性的,只有在需要返回下一个数据时它才会计算。
Iterator甚至可以表示一个无限大的数据流,例如全体自然数。而使用list是永远不可能存储全体自然数的。
小结
凡是可作用于for循环的对象都是Iterable类型;
凡是可作用于next()函数的对象都是Iterator类型,它们表示一个惰性计算的序列;
集合数据类型如list、dict、str等是Iterable但不是Iterator,不过可以通过iter()函数获得一个Iterator对象。
Python的for循环本质上就是通过不断调用next()函数实现.
内置函数
- print(abs(-10.1)) #绝对值函数abs
- list=[1,21,None]
- print(all(list)) # 全为真,才为真 False
- print(any(list)) # 只用有一个为真,就全为真 True
- print(bool(1)) # 非零即为真
- print(bin(5)) # 转化成二进制 ob
- print(oct(9)) # 转化成八进制0o
- print(hex(10)) # 转化成十六进制0x
- bytes() # 将字符串转化成字节类型,例如:
- print(len(bytes("李杰",encoding="utf-8")))
- print(len(bytes("汉字",encoding="gbk")))
- # 一个汉字在utf-8中占用三个字节。
- # 一个汉字在gbk中占用两个字节。
- print(chr(98)) # 将对应的十进制数转化转化成ascii中对应的字母
- print(ord('a')) # 将字符转成ASCII码中对应的十进制数字。
- result = eval("8*8") # 64 eval():格式:eval( obj[, globals=globals(), locals=locals()] ), 运算符,表达式:只能执行运算符,表达式, 并且eval() 有返回值
- result = exec("8*8") # none 格式:exec(obj),执行代码或者字符串,没有返回值,执行代码时,接收代码或者字符串
- dir(list) # 快速查看对象有哪些功能
- print(divmod(10,2)) #(5,0)divmod() :求商和余数,返回数据类型是元组,常用于页面分页计算
- s = "alex"
- print(isinstance(s,str)) # 判断对象是否为某一个类的实例 isinstance
- #filter(func,obj):过滤,其中obj为可迭代的对象, 循环第二个参数,将每一个循环元素,去执行第一个参数(函数),如果函数的返回值为True,即合法
- #filter()用来筛选,函数返回True,将元素添加到结果中。
- li=[1,23,11,34]
- result = filter(lambda x:x>11,li) # 数组,返回的是一个生成器。
- #print(type(result))
- print(result.__next__())
- print(result.__next__())
- #print(result.__next__())
- #print(result)
- #filter()是使用函数对可迭代对象进行筛选,如果函数返回为True,将对象添加到结果中
- #map()是使用函数对可迭代对象进行处理,批量操作,将函数返回值添加到结果中
- result = map(lambda x:x+100,li)
- print(result) # 返回一个内存地址
- #print(list(result)) #101 123 111 134
- s=hash("nihao") # 生成hash值,
- #min() 求最小
- #max() 求最大
- #sum() 求和
- print(round(1.4)) #round 四舍五入
- print(pow(10,3)) # 求幂 10*10*10
- list1=[1,2,3,4]
- list2=[5,6,6,8]
- print(zip(list1,list2)) # 返回一个内存地址
- print(list(zip(list1,list2))) # 返回一个元组(1,4),(2,6)(3,6),(4,8)
pickle和json
用于序列化的两个模块
json,用于字符串 和 python数据类型间进行转换
pickle,用于python特有的类型 和 python的数据类型间进行转换
Json模块提供了四个功能:dumps、loads、dump、load
pickle模块提供了四个功能:dumps、loads、dump、load
dumps和loads
- import pickle,json
- data = {'k1':123, 'k2':123}
- #dumps可以将数据类型转换成只有python才认识的字符串
- p_str = pickle.dumps(data)
- print(p_str) # '\x80\x03}q\x00(X\x02\x00\x00\x00k2q\x01K{X\x02\x00\x00\x00k1q\x02K{u.'
- # 将数据转化成python认识的字符串,并写入到文件
- data = {'k1':123, 'k2':123}
- #打开文件,然后将data写入
- with open('data.pkl', 'wb') as f:
- pickle.dump(data, f)
- #同样读取的时候也需要打开文件
- with open('data.pkl', 'rb') as f:
- data_1 = pickle.load(f)
- print(data_1,type(data_1))
- import json
- data = {'k1':123, 'k2':123}
- p_str = json.dumps(data)
- print(p_str, type(p_str)) # {"k2": 123, "k1": 123} <class 'str'>
- data = {'k1':123, 'k2':123}
- #打开文件,然后将data写入
- with open('data.pkl', 'w') as f:
- json.dump(data, f)
- #同样读取的时候也需要打开文件
- with open('data.pkl', 'r') as f:
- data_1 = json.load(f)
- print(data_1, type(data_1))
- pickle和json的区别?
在上面两段代码中,pickle写入和读取文件时,用的是 ‘b’模式,而json没有。json是可以在不同语言之间交换数据的,而pickle只在python之间使用。
json只能序列化最基本的数据类型,而pickle可以序列化所有的数据类型,包括类,函数都可以序列化。pickle转成成的字符串时字节数组,json转换的字符串是str类型。
python自动化运维之路04的更多相关文章
- python自动化运维之路~DAY5
python自动化运维之路~DAY5 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.模块的分类 模块,用一砣代码实现了某个功能的代码集合. 类似于函数式编程和面向过程编程,函数 ...
- Python自动化运维之路-01
python的主要应用 python的擅长领域 学python有没有前途?python的语言排名 语言选择 运维会了开发后可以干什么? python的最大优势就是什么都能做. 课程概述 毕业目标 周五 ...
- 《Python自动化运维之路》 业务服务监控(二)
文件内容差异对比方法 使用diffie模块实现文件内容差异对比.dmib作为 Python的标准库模块,无需安装,作用是对比文本之间的差异,且支持输出可读性比较强的HTML文档,与 Linux下的di ...
- 《Python自动化运维之路》 系统基础信息模块(一)
系统性能收集模块Psutil 目录: 系统性能信息模块psutil 系统性能信息模块psutil psutil能够轻松实现获取系统运行的进程和系统利用率包括(CPU,内存,磁盘 和网络)等.主要用于系 ...
- 【Python自动化运维之路Day9】Socket
socket也可以认为是套接字是一种源IP地址和目的IP地址以及源端口号和目的端口号的组合.网络化的应用程序在开始任何通讯之前都必须要创建套接字.就像电话的插口一样,没有它就没办法通讯. socket ...
- 【Python自动化运维之路Day7】
1. configparser模块 import configparser config = configparser.ConfigParser() #先把config应用一下configparser ...
- 【Python自动化运维之路Day6】
1.递归思考题,阶乘 使用递归方式(函数)计算: 1*2*3*4*5*6*7*8*9*10的值 def func(num): if num==1: return 1 return num*func(n ...
- 【Python自动化运维之路Day4】
abs() 取绝对值all() 所有为真,则为真,否则为假any() 至少有一个为真,就为真,否则为假callable() 判断函数是否可以被调用,如果可以返回True,否则返回False ...
- 【Python自动化运维之路Day2】
1. 常量命名规则 在Python中,会在变量命名上标明某变量是常量,通常采用全是大写的方式来标明,如: CONNECT= '127.0.0.1' PORT = ' 2.Python编译 python ...
随机推荐
- 《Python程序设计(第3版)》[美] 约翰·策勒(John Zelle) 第 1 章 答案
判断对错1.计算机科学是计算机的研究.2.CPU 是计算机的“大脑”.3.辅助存储器也称为 RAM.4.计算机当前正在处理的所有信息都存储在主存储器中.5.语言的语法是它的意思,语义是它的形式.6.函 ...
- C#中值和引用
c#中有两种基本类型,它们分别是值类型和引用类型:而每种类型都可以细分为如下类型: ps:1.基本类型是值类型 2.类.接口.委托都是引用类型
- bootstrap的carousel图片轮播
整个轮播是放在一个div .carousel和.slide的div中的, 包括3个部分: 1. 第一个部分indicator位于下方的指示器部分. 结构是一个ol和li, ol的类是carousel- ...
- P3216 [HNOI2011]数学作业 (矩阵快速幂)
P3216 [HNOI2011]数学作业 题目描述 小 C 数学成绩优异,于是老师给小 C 留了一道非常难的数学作业题: 给定正整数 NN 和 MM ,要求计算 Concatenate (1 .. N ...
- 分布式系统一致性算法Raft
Raft 算法也是一种少数服从多数的算法,在任何时候一个服务器可以扮演以下角色之一:Leader:负责 Client 交互 和 log 复制,同一时刻系统中最多存在一个Follower:被动响应请求 ...
- django查询集API
本节将详细介绍查询集的API,它建立在下面的模型基础上,与上一节的模型相同: from django.db import models class Blog(models.Model): name = ...
- Qt5_QString_测试
ZC: 下面的测试效果看,可以只是用 “QString.isEmpty()” 或者 “QString == ""”来判断 QString是否为 空或者NULL . 1. 1.1. ...
- Hashtable、HashMap、TreeMap心得
三者均实现了Map接口,存储的内容是基于key-value的键值对映射,一个映射不能有重复的键,一个键最多只能映射一个值. (1) 元素特性 HashTable中的key.value都不能为null; ...
- SQL脚本去重分组统计
需求:首先有一张表记录学生姓名.科目和成绩,然后模拟插入几条数据,脚本如下: create table score ( Name ),--姓名 subject ),--科目 grade int--成绩 ...
- C++STL1--set
C++STL1--set 一.说明 set的用法:单一元素,自动排序set的方法:用编译器的提示功能即可,不需要自己记 二.简单测试 /* 安迪的第一个字典 set的用法:单一元素,自动排序 set的 ...