一、装饰器
装饰器可以使函数执行前和执行后分别执行其他的附加功能,这种在代码运行期间动态增加功能的方式,称之为“装饰器”(Decorator),装饰器的功能非常强大。装饰器一般接受一个函数对象作为参数,以对其进行增强 ,相当于C++中的构造函数,与析构函数。
特点:
- 装饰器本身是一个函数,用于装饰其他函数。
- 装饰器是一个闭包函数是嵌套函数,通过外层函数提供嵌套函数的环境。
- 装饰器在权限控制,增加额外功能如日志,发送邮件用的比较多。
1,原函数不带参数的装饰器
假设:我定义了一个函数lyshark,现在想要在不改变原来函数定义的情况下,在函数运行前打印一段话,函数运行后打印另一段话,要实现这样一个功能该怎么实现?看以下实现方式:
>>> import os >>> import sys >>> >>> def outer(function): def inner(): print("主函数执行前,应先执行我!") result=function() print("主函数执行后,要执行我!") return result return inner
# (1) @ + 函数名 直接作用在需要装饰的函数上一行
# (2)自动执行outer函数并且将下面的函数名lyshark()当做参数传递到outer()
# (3)将outer函数的返回值inner,重新赋值给lyshark()函数
>>> @outer def lyshark(): print("lyshark 的主函数体,装饰器在装饰我(*^_^*)") return "lyshark 返回了" >>> ret=lyshark() 主函数执行前,应先执行我! lyshark 的主函数体,装饰器在装饰我(*^_^*) 主函数执行后,要执行我! >>> >>> print("lyshark()函数的返回值: ",ret) lyshark()函数的返回值: lyshark 返回了 >>>
2,原函数带一个参数的装饰器
假设:我们在前面的基础上给函数传递一个参数看看,它有啥反应,刺激一下它
>>> import os >>> import sys >>> >>> def outer(function): def inner(args): print("主函数执行前,应先执行我!") ret=function(args) print("主函数执行后,要执行我!") return ret return inner >>> @outer def lyshark(args): print(args) return "lyshark 返回了" >>> >>> ret=lyshark("hello world!") 主函数执行前,应先执行我! hello world! 主函数执行后,要执行我! >>> >>> print("lyshark 的返回值是:",ret) lyshark() 函数的返回值是: lyshark 返回了 >>> >>>
3,原函数带两个参数的装饰器
假设:我们在前面的基础上给函数传递两个参数看看,它有啥反应,刺激一下它
>>> import os >>> import sys >>> >>> >>> def outer(function): def inner(x,y): print("主函数执行前,应先执行我!") ret=function(x,y) print("主函数执行后,要执行我!") return ret return inner >>> @outer def lyshark(x,y): print(x,y) return "lyshark 返回了" >>> >>> ret=lyshark("Hello","LyShark") 主函数执行前,应先执行我! Hello LyShark 主函数执行后,要执行我! >>> >>> print("lyshark() 函数的返回值是:",ret) lyshark() 函数的返回值是: lyshark 返回了 >>> >>>
4,传递一个万能参数
>>> import os >>> import sys >>> >>> def outer(function): def inner(*args,**kwargs): print("主函数执行前,应先执行我!") ret=function(*args,**kwargs) print("主函数执行后,要执行我!") return ret return inner >>> >>> @outer def lyshark(*args): print(args) return "lyshark 返回了" >>> >>> num=[1,2,3,4,5] >>> ret=lyshark(num) 主函数执行前,应先执行我! ([1, 2, 3, 4, 5],) 主函数执行后,要执行我! >>> >>> print("lyshark() 函数的返回值是:",ret) lyshark() 函数的返回值是: lyshark 返回了 >>> >>>
5,一次使用两个装饰器装饰函数
如果一个装饰器不够用的话,我们可以使用两个装饰器,首先将函数与内层装饰器结合然后在与外层装饰器相结合,要理解使用@语法的时候到底执行了什么,是理解装饰器的关键。
>>> import os >>> import sys >>> >>> def outer2(function2): def inner2(*args,**kwargs): print("装饰器2,【开始】") ret=function2(*args,**kwargs) print("装饰器2,【结束】") return ret return inner2 >>> def outer1(function1): def inner1(*args,**kwargs): print("装饰器1,【开始】") ret=function1(*args,**kwargs) print("装饰器1,【结束】") return ret return inner1 >>> >>> @outer2 @outer1 def lyshark(): print("lyshark 函数执行了!") >>> lyshark() 装饰器2,【开始】 装饰器1,【开始】 lyshark 函数执行了! 装饰器1,【结束】 装饰器2,【结束】 >>>
6,给装饰器添加参数
前面的例子中,装饰器本身没有带参数,如果要写一个带参数的装饰器怎么办,下面我们就实现一个三层的装饰器。
>>> import functools >>> import sys >>> >>> def lyshark(temp=""): #指定装饰器默认参数 def decorator(function): @functools.wraps(function) #使被装饰的装饰器的函数名不改变 def wrapper(*args,**kwargs): print("主函数执行前,应先执行我!") print("{}:{}".format(temp,function.__name__)) #这里调用了装饰器temp变量 ret=function(*args,**kwargs) print("主函数执行后,要执行我!") return ret return wrapper return decorator >>> #如果不给装饰器加参数,那么这个装饰器将使用默认参数 temp=" " >>> @lyshark() def test(x): print(x+100) >>> test(100) 主函数执行前,应先执行我! :test 200 主函数执行后,要执行我! >>>
>>> #下面是给装饰器一个参数,将不是用默认参数 temp=" "将变成 temp="LyShark" >>> @lyshark("LyShark") def test(x): print(x+100) >>> test(100) 主函数执行前,应先执行我! LyShark:test 200 主函数执行后,要执行我! >>>
>>> import sys >>> import os >>> >>> def lyshark(x="Hello",y="LyShark"): def decorator(function): def wrapper(): print("主函数执行前,应先执行我!") print(x,y) ret=function() print("主函数执行后,要执行我!") return ret return wrapper return decorator >>> >>> #使用默认参数的装饰器 : 此时 x="Hello" y="LyShark" >>> @lyshark() def test(): print("我是test(),主函数,装饰器在装饰我") >>> test() 主函数执行前,应先执行我! Hello LyShark 我是test(),主函数,装饰器在装饰我 主函数执行后,要执行我! >>> >>> #给装饰器指定参数 : 此时 x="My Name Is :" y="LyShark" >>> >>> @lyshark("My Name Is :","LyShark") def test(): print("我是test(),主函数,装饰器在装饰我") >>> test() 主函数执行前,应先执行我! My Name Is : LyShark 我是test(),主函数,装饰器在装饰我 主函数执行后,要执行我! >>>
小总结
#使用装饰器函数实现,记录登陆状态
import os import sys user_info={} def check_login(func): def inner(): if ((user_info.get("is_login",None) == True) and (user_info.get("user_type",None) == 0)): print("\n\n\n尊敬的LyShark,您好 \n\n\n") #ret=func() #return ret else: print("\n\n\n您没有登陆,请登录!!!\n\n") return inner def root_login(): user=input("输入用户名: ") if (user == "lyshark"): passwd=input("输入密码: ") if (passwd == "123123"): user_info["is_login"]=True user_info["user_type"]=0 print("登陆成功,您的登陆状态已被记录!\n\n") else: print("您输入的密码不正确!\n\n") else: print("您输入的用户名不正确!\n\n") @check_login def user_index(): print("index") def main(): while True: temp=input("1.用户登录 2.查看信息 \n LyShark --> ") if (temp =="1"): root_login() elif (temp =="2"): user_index() else: continue main()
USER_INFO = {} def check_login(func): def inner(*args,**kwargs): if USER_INFO.get('is_login',None): ret = func() return ret else: print("请登录") return inner def check_admin(func): def inner(*args,**kwargs): if USER_INFO.get('user_type',None) == 2: ret = func() return ret else: print("无权限查看") return inner @check_login #先检查你是不是登陆了 @check_admin #在检查你是不是管理员 路子很野啊,小伙子!! def index(): """ 管理员用户 """ print('index') @check_login def home(): """ 普通用户 """ print('home') def login(): user = input("请输入用户名:") if user == 'admin': USER_INFO['is_login'] = True USER_INFO['user_type'] = 2 else: USER_INFO['is_login'] = True USER_INFO['user_type'] = 1 def main(): while True: inp = input('1、登录;2、查看信息;3、超级管理员管理\n>:') if inp == '1': login() elif inp == '2': home() elif inp == '3': index() main()
二、生成器
- 跟普通函数不同的是,生成器是一个返回迭代器的函数,只能用于迭代操作,更简单点理解生成器就是一个迭代器。
- 在 Python 中,使用了 yield 的函数被称为生成器(generator)。
- 在调用生成器运行的过程中,每次遇到 yield 时函数会暂停并保存当前所有的运行信息,返回 yield 的值, 并在下一次执行 next() 方法时从当前位置继续运行。
- 调用一个生成器函数,返回的是一个迭代器对象。
生成器的一些例子
【实例】
#一个最简单的生成器
>>> import sys >>> >>> def function(): #此函数就是一个生成器函数 yield 1 yield 2 yield 3 yield 4 yield 5 >>> temp=function() #实例化 >>> >>> temp.__next__() #开始迭代 1 >>> temp.__next__() 2 >>> temp.__next__() 3 >>> temp.__next__() 4 >>> temp.__next__() 5 >>>
#使用while循环构建一个生成器,并通过for遍历
>>> import sys >>> >>> def yieldNum(x): y=0 while (y <= x): yield y y += 1 >>> yie=yieldNum(4) >>> >>> next(yie) 0 >>> >>> for i in yie: print(i) 1 2 3 4 >>>
#使用生成器求1-10的平方
>>> def yieldNum(): x=1 while (x <=10 ): yield x ** 2 x += 1 >>> yie=yieldNum() >>> >>> for i in yie: print(i) 1 4 9 16 25 36 49 64 81 100 >>>
#使用生成器自定义range函数
>>> def xrange(num): temp=-1 while True: temp=temp+1 if (temp >= num): return else: yield temp >>> xrange(10) <generator object xrange at 0x038E3030>
#生成器求斐波那契数列
>>> def fib(max): n,a,b=0,0,1 while n < max: yield b a,b=b,a+b n+=1 return "done" >>> >>> >>> f=fib(5) >>> >>> f <generator object fib at 0x038F4A20>
列表解析
列表解析是python迭代机制的一种应用,它常用于实现创建新的列表,因此要放置于[]中
【实例】
>>> temp=[1,2,3,4] >>> >>> temp1=[ x ** 2 for x in temp ] >>> temp [1, 2, 3, 4] >>> temp1 [1, 4, 9, 16]
>>> temp [1, 2, 3, 4] >>> >>> temp1=[ x**2 for x in temp if x >=2 ] >>> temp1 [4, 9, 16] >>>
>>> temp [1, 2, 3, 4] >>> >>> temp1=[ (i**2)/2 for i in range(1,10) ] >>> temp1 [0.5, 2.0, 4.5, 8.0, 12.5, 18.0, 24.5, 32.0, 40.5] >>>
>>> temp1=["x","y","z"] >>> temp2=[1,2,3] >>> temp3=[ (i,j) for i in temp1 for j in temp2 ] >>> temp3 [('x', 1), ('x', 2), ('x', 3), ('y', 1), ('y', 2), ('y', 3), ('z', 1), ('z', 2), ('z', 3)] >>>
>>> import os >>> >>> file_list=os.listdir("/var/log") >>> file_log=[ i for i in file_list if i.endswith(".log") ] >>> print(file_log) ['boot.log', 'yum.log', 'ecs_network_optimization.log', 'ntp.log'] >>> >>> >>> file_log=[ i for i in os.listdir("/var/log") if i.endswith(".log") ] >>> print(file_log) ['boot.log', 'yum.log', 'ecs_network_optimization.log', 'ntp.log'] >>>
生成器表达式
生成器表达式并不真正创建数字列表,而是返回一个生成器对象,此对象在每次计算出一个条目后,把这个条目“产生”(yield)出来
生成器表达式使用了"惰性计算"或称作"延迟求值"的机制
序列过长,并且每次只需要获取一个元素时,应当考虑使用生成器表达式而不是列表解析
>>> import sys >>> >>> yie=( i**2 for i in range(1,10) ) >>> next(yie) 1 >>> next(yie) 4 >>> next(yie) 9 >>>
>>> for j in ( i**2 for i in range(1,10)):print(j/2) ... 0.5 2.0 4.5 8.0 12.5 18.0 24.5 32.0 40.5 >>>
三、迭代器
迭代器是访问集合元素的一种方式。迭代器对象从集合的第一个元素开始访问,直到所有的元素被访问完结束。迭代器只能往前不会后退,不过这也没什么,因为人们很少在迭代途中往后退。另外,迭代器的一大优点是不要求事先准备好整个迭代过程中所有的元素。迭代器仅仅在迭代到某个元素时才计算该元素,而在这之前或之后,元素可以不存在或者被销毁。这个特点使得它特别适合用于遍历一些巨大的或是无限的集合,比如几个G文件的遍历。
特点:
- 迭代是Python最强大的功能之一,是访问集合元素的一种方式。
- 迭代器对象从集合的第一个元素开始访问,直到所有的元素被访问完结束。迭代器只能往前不会后退。
- 迭代器是一个可以记住遍历的位置的对象。
- 迭代器有两个基本的方法:iter() 和 next()。
- 字符串,列表或元组对象都可用于创建迭代器。
- 迭代器便于循环比较大的数据集合,节省了内存开支。
- 访问者不需要关心迭代器内部的结构,仅需通过next()方法不断去取下一个内容。
- next()就相当于调用__next__(),for也是iterable(可迭代)对象。
迭代器的基本用法
>>> import sys >>> >>> temp=iter([1,2,3,4,5,6,7,8,9]) >>> >>> temp <list_iterator object at 0x03BD1F90> >>> temp.__next__() 1 >>> temp.__next__() 2 >>> temp.__next__() 3 >>>
或者
>>> import sys >>> >>> temp=[1,2,3,4,5] >>> >>> ite=temp.__iter__() >>> >>> print(type(temp),type(ite)) <class 'list'> <class 'list_iterator'> >>> >>> next(ite) 1 >>> >>> next(ite) 2 >>> next(ite) 3 >>> next(ite) 4 >>>
迭代的另一种遍历方式
>>> ite=iter([1,2,3,4,5]) >>> >>> while True: try: temp=next(ite) print(temp) except StopIteration: break 1 2 3 4 5
参考文献:https://www.runoob.com/
参考文献:https://www.cnblogs.com/