python有三大神器,分别是迭代器、生成器以及装饰器,本篇就是用来简要汇总下三大神器的用法
在python中可以遍历字符串、列表、元组、字典、集合等数据类型,也叫迭代,这些数据类型也叫做可迭代对象,
可迭代的对象有其独有的方法,以列表为例(源码)
class list(object):
"""
Built-in mutable sequence.
If no argument is given, the constructor creates a new empty list.
The argument must be an iterable if specified.
"""
def __iter__(self, *args, **kwargs): # real signature unknown
""" Implement iter(self). """
pass
也就是说一个对象有__item__
的方法,它就是一个可迭代的对象,就可以用来遍历
回过去看range的可以发现它也有__item__
方法,所以它也是可迭代对象
迭代器是一个可以记住遍历的位置的对象,简单理解就是盛放可迭代对象的容器。
# 创建一个迭代器
a = iter((1,2,3,4))
print(a)
print(next(a))
print(next(a))
# 输出结果
<tuple_iterator object at 0x000001F6E5878CF8>
1
2
可以发现位置已被记住,按顺序输出,所以迭代器不仅仅有__item__
的方法,同时还必须有__next__
方法,用来记住位置。
可节省内存空间
按顺序取值,直到取完为止
import sys
a = [x for x in range(1000000)]
print(sys.getsizeof(a)) # 查看占用内存空间
it = iter(a)
print(sys.getsizeof(it))
# 输出结果如下:
8697464
56
生成器本质上也是迭代器,只是在实现的方式上更简洁。
A = [x for x in range(10)]
print(A)
B = (x for x in range(10))
print(B)
# 输出结果如下:
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
<generator object <genexpr> at 0x000001DBBD2A2840>
仔细观察A、B几乎无差异仅仅是外面括号的不同,侧面证明元组是不可变对象,是不可以新增元素的,所以python把它变成了一种创建生成器的方法
def test(n):
for i in range(n):
yield i
a = test(5)
print(a)
print(next(a))
print(next(a))
# 输出结果如下:
0
1
<generator object test at 0x000002C14FCD2840>
yield的理解
闭包就是能够读取其他函数内部变量的函数。可以理解成“定义在一个函数内部的函数“。在本质上,闭包是将函数内部和函数外部连接起来的桥梁。 – 百度百科
或许看完这个百度百科的解释,更容易糊涂,拿个小案例来解释一下
def line(k,b):
def res(x):
return k * x + b
return res
outer = line(3,2)
# 运行到这里 理论上局部变量k = 3和b = 2会被清除
inner = outer(5)
# 但是在这里的时候还是被记住了
print(inner)
# 输出结果
17
在一个函数line中定义了另一个函数res,res这个函数运用了调用line函数时的临时变量,并且最后的返回值是res函数的返回值,这样就构成了一个闭包
语法糖(Syntactic sugar),也译为糖衣语法,是由英国计算机科学家彼得·约翰·兰达(Peter J. Landin)发明的一个术语,指计算机语言中添加的某种语法,这种语法对语言的功能并没有影响,但是更方便程序员使用。通常来说使用语法糖能够增加程序的可读性,从而减少程序代码出错的机会。 – 百度百科
python中语法糖较多,常见的像推导式,yield等都属于语法糖的一种.而装饰器是最重要的一种语法糖
作用: 用于拓展原来函数功能的一种函数,可以在不用更改原函数的代码前提下给函数增加新的功能
关键语法糖符号 @
案例
如在很多时候都需要有登录信息,但是如果某一个模块已经写完了,为了不修改已完成的代码可以使用装饰器
def login(func):
print('需要登录信息')
def check(*args,**kwargs):
print('验证完成')
return func(*args,**kwargs)
return check
@login
def test(*args,**kwargs):
print('开始查询')
return '查询完毕'
print(test())
# 不加装饰器输出结果如下:
开始查询
查询完毕
# 加上装饰器:
需要登录信息
验证完成
开始查询
查询完毕