(五) 学习笔记:python的装饰器,生成器和迭代器

装饰器

装饰器本质是一个python函数,它可以在让其他函数不需要任何代码变动的前提下增加额外的功能,装饰器的返回值是一个函数对象
实例:

def demo(arg):
    def inner(age):   # 内部的函数
        if age <= 10:
            myStr = "儿童"
        elif age <= 20:
            myStr = '青年'
        elif age <= 50:
            myStr = "中年"
        else:
          myStr = "老年人"
        arg(myStr)
 return inner  # 返回内部函数对象
def mySpeak(person):
    print("你是一个{}年龄段的人.".format(person))

# 不使用语法糖@
print(demo(mySpeak))  # demo..inner
a = demo(mySpeak)
a(20)  # 你是一个青年年龄段的人, 调用了内部的函数

# 还可以将变量a改为和mySpeak同名
mySpeak = demo(mySpeak)
mySpeak(20)  # 你是一个青年年龄段的人, 调用mySpeak实质调用了内部的inner函数,

# 使用@语法糖, 在定义函数的时候,避免了赋值的操作
@demo
def mySpeak(person):
      pass   

列表推导式

利用其它列表推导出新的列表。
它不是真正的语句,而是类似于循环的表达式——轻量级的循环,可以极大的简化代码。

实例(bb is cheap):

# 我想得到一个1-9的列表
# 方法一: 使用循环遍历
newList = []
for i in range(1,10):
    newList.append(i)
print(newList)  # 输出[1, 2, 3, 4, 5, 6, 7, 8, 9]
# 方法二:使用列表推导式
newList = [i for i in range(1,10)]
print(newList)  # 输出[1, 2, 3, 4, 5, 6, 7, 8, 9] 可以看到使用列表推导式是不是特别简单,特别装逼,高端大气上档次。

# 我现在需求变了,我生成一个列表,值为1-9的平方
# 使用列表推导式
newList = [i**2 for i in range(1,10)]
print(newList)   # [1,4,9,....]

# 我现在需求又变了,我想获取列表中偶数的平方
# 如果使用for循环遍历,你可能会这样写代码
newList = []
for i in range(1,10):
   if i % 2 == 0:
        newList.append(i**2)
print(newList)
# 但是使用列表推导式,只需这样
newList = [i**2 for i in range(1,10) if i %2==0]
print(newList)  # [4, 16, 36, 64]

# 快速生成二维列表
newList = [[x,y] for x in range(1,4) for y in range(1,5)]
print(newList)  # [[1,1],[1,2],[1,3],[1,4], [2,1],....] 太多就不写完了
# 生成偶数的平方的二维列表
newList = [[i,i**2] for i in range(1,10) if i % 2==0]
print(newList)  # [[2,4], [4,16], [6,36], [8,64]]

# 将一个3*4的矩阵变为4*3的矩阵
# 例如:将myList = [[1, 2, 3, 4], [5, 6, 7, 8], [9, 10, 11, 12]] 变成
myList = [[1,5,9],[2,6,10],[3,7,11],[4,8,12]]
#  这个如果使用for循环
newList2 = []
for i in range(1,4):
      newList1 = []
      for j in range(1,5):
          newList1.append(j[i])
      newList2.append(newList1)
print(newList2)  # 达到想要的结果
# 但如果使用列表推导式,你只需这样
newList = newList = [j[i] for j in myList] for i in range(4)]

迭代器

可迭代对象(iterable): 可以直接被for循环等遍历。
通过使用isinstance() 可以判断是否为可迭代对象。
实例:

from collections import Iterable
print(isinstance(1,Iterable))  # False  整形不为可迭代对象
print(isinstance(1.2, Iterable))  # False 浮点型也不为可迭代对象
print(isinstance(“abcd”, Iterable))  # True 字符串可被遍历
print(isinstance((), Iterable)  # True 元组也为可迭代对象
print(isinstance([], Iterable))  # True
print(isinstance({1,2}, Iterable))  # True  集合可以遍历
print(isinstance(True,Iterable))  # False

迭代器(iterator):
前提条件:
1.迭代器必须是一个可迭代对象
2.迭代器有两个基本的方法iter(), next()
3.也可使用isinstance()来判断是否为迭代器
4.迭代器只能不断向后走(向后遍历, 只能循环一次), 遍历完会报stopIteration异常
注意:一个实现了__iter__方法的对象时可迭代的,一个实现了__next__方法的对象时迭代器。
实例:

# 导入迭代器
from collecions import Iterator
myIterator = iter(‘abc’)
print(myIterator)  #  输出迭代器对象

生成器:
使用生成器, 可以节约电脑的资源
1.使用列表推导式将[]改为()创建一个简单的生成器
2.使用了yield关键字的函数变为一个生成器
3.生成器也可以使用迭代器的__next__方法一个一个取值
使用列表推导式写法的实例:

# 如果为列表推导式,定义一个很大的列表
myList = [i for i in range(10000000)]  #  占用了大量的内存空间
# 使用生成器边使用边生产,节约电脑资源
myList = (i for i in range(10000000))  # 用小括号表示
print(type(myList))  # generator 
# 可以使用next进行取值
print(next(myList))  # 0
print(next(myList))  # 1
print(next(myList))  # 2

使用yield关键字的生成器函数:

def demo():
  for i in range(10):
      print(i)
      yield  i  #  加上参数 会将参数返回,不加参数返回None

print(type(demo()))  # 
myGen = demo()  
next(myGen)  # 0
next(myGen)  # 1
next(myGen)  # 2
# 也可以使用for循环遍历
for i in myGen:
      print(i)

你可能感兴趣的:((五) 学习笔记:python的装饰器,生成器和迭代器)