(五) 学习笔记: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.<locals>.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)  #  输出迭代器对象<str_iterator object at 0x0000..
#  可以使用isinstance() 判断是否为迭代器
print(isinstance(myIterator, Iterator))  # True
print(isinstance('abc', Iterator))  # False "abc"为可迭代对象不为迭代器
# 可以使用next()方法取值
print(next(myIterator )) # a
print(next(myIterator ))  # b 会继续上次向后输出
print(next(myIterator )) # c
print(next(myIterator ))  # error StopIteration

# 使用for循环遍历迭代器
for i in myIterator :
    print(i)  # 最后输出结果 a b c

生成器:
使用生成器, 可以节约电脑的资源
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()))  # <generator object demo at 0x...>
myGen = demo()  
next(myGen)  # 0
next(myGen)  # 1
next(myGen)  # 2
# 也可以使用for循环遍历
for i in myGen:
      print(i)
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 205,874评论 6 479
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 88,151评论 2 382
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 152,270评论 0 342
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 55,137评论 1 278
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 64,116评论 5 370
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,935评论 1 283
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,261评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,895评论 0 259
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 43,342评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,854评论 2 323
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,978评论 1 333
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,609评论 4 322
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,181评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,182评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,402评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,376评论 2 352
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,677评论 2 344

推荐阅读更多精彩内容