巨蟒python全栈开发-第11天 第一类对象 闭包 迭代器

一.今日主要内容总览(重点)

1.第一类对象->函数名=>变量名
(1)函数对象可以像变量一样进行赋值
(2)还可以作为列表的元素进行使用
(3)还可以作为返回值返回
(4)还可以作为参数进行传递

思想:函数名就是变量名
(不仅指向一块空间,还有自身的意义)

2.闭包->函数的嵌套
(1)内层函数对外层函数中的变量的使用
(2)好处:
1.保护变量不被侵害
2.让一个变量常驻内存

(3)如何通过代码查看一个闭包?
__closure__: 有东西就是闭包,没东西就不是闭包

(4)迭代器=>固定的思路.for循环
一个数据类型中包含了__iter__函数表示这个数据是可迭代的
dir(数据):返回这个数据可以执行的所有操作

(5) 判断迭代器和可迭代对象的方案(野路子)
__iter__ 可迭代的
__iter__ __next__ 迭代器

(6)判断迭代器和可迭代对象的方案(官方)
from collections import Iterable, Iterator
isinstance(对象, Iterable) 是否是可迭代的
isinstance(对象, Iterator) 是否是迭代器


(7)模拟for循环
lst=[]
#拿迭代器
it=lst.__iter__()
while 1:
try:
it.__next__()
excep StopIteration:
break

#特征:
为了保证安全,我们在内部调用
1. 省内存(生成器)
2. 惰性机制
3. 只能向前. 不能后退

作用:统一了各种数据类型的遍历

3.迭代器->固定的思路.for循环
for循环的底层意义

二.今日内容大纲

1.第一类对象

2.闭包

3.迭代器

三.内容详解

1.第一类对象

(1)

def fn():
    print('我叫fn')
print(fn)#结果:<function fn at 0x0000025672D298C8>

(2)

def fn():
    print('我叫fn')
fn()
print(fn)
gn=fn         #函数名可以进行赋值操作
print(gn)
gn()
'''
结果:
<function fn at 0x00000185567798C8>
<function fn at 0x00000185567798C8>
'''

(3)

def func1():
    print('朱元璋')
def func2():
    print('朱祁镇')
def func3():
    print('徐洁')
def func4():
    print('魏忠贤')
#操作一
lst=[func1,func2,func3,func4]#列表中什么都可以放,没有数据类型的限制
print(lst)  #结果:朱元璋
#操作二:
lst[0]()
#操作三:
for el in lst:  #el是列表中的每一项.
    el()        #拿到函数,执行函数
'''
结果:
朱元璋
朱祁镇
徐洁
魏忠贤
'''

(4)

def func1():
    print('朱元璋')
def func2():
    print('朱祁镇')
def func3():
    print('徐阶')
def func4():
    print('魏忠贤')
#操作一
lst=[func1(),func2(),func3(),func4()]
print(lst)
'''
结果:#总结:先调用每一个,因为没有返回值,只能是4个None
朱元璋
朱祁镇
徐洁
魏忠贤
[None, None, None, None]
'''

(5)

a=10
b=20
c=30
lst=[a,b,c]
print(lst)
'''
结果:
[10, 20, 30]

(6)

a=10
b=20
c=30
lst=[a,b,c]
print(lst)
'''
结果:
[10, 20, 30]
'''
#通过(4)和(5),发现变量和函数的操作是一样的,变量可能数据类型不同
#函数数据类型相同,变量的每次数据类型不一定相同
(6)#重点降临
def wrapper():
    def inner():
        print('我的天,还可以这样?')
    print(inner)    #<function wrapper.<locals>.inner at 0x0000021F4F929950>
    # inner()
    return inner
ret=wrapper()
print(ret)          #<function wrapper.<locals>.inner at 0x0000021F4F929950>
(6-1)
def wrapper():
    def inner():
        print('我的天,还可以这样?')
    print(inner)    #<function wrapper.<locals>.inner at 0x0000021F4F929950>
    # inner()
    return inner
ret=wrapper()
print(ret)          ##<function wrapper.<locals>.inner at 0x0000021F4F929950>
ret()                #我的天,还可以这样?
#总结:在函数外部访问了函数内部的函数
'''
结果:
<function wrapper.<locals>.inner at 0x000001F1B8609950>
<function wrapper.<locals>.inner at 0x000001F1B8609950>
我的天,还可以这样?
'''

(7)

def wrapper():
    def inner():
        print('大冬瓜')
    return inner #函数名可以向返回值一样返回#返回的是inner,也就是ret
ret=wrapper()
ret()   #在函数外面访问了函数内部的函数
ret()
ret()

结果:

大冬瓜
大冬瓜
大冬瓜

(8)

def func1():
    print('谢晋')
def func2():
    print('杨士奇')
def func3():
    print('徐渭')
def func4():
    print('柳如是')

#代理函数
#代理,也是装饰器的雏形
def proxy(a):   #a就是变量,形参
#函数作为参数进行传递
    #代理好处,可以加点东西
    print('我是代理')
    a()
    print('代理执行完毕')
proxy(func1)
proxy(func3)
proxy(func4)
总结:函数名就是变量名
1.函数名可以像变量一样进行传递
2.函数名可以作为参数进行赋值操作
3.可以作为返回值返回
4.可以作为参数进行传递

2.闭包

(1)

def wrapper():
    name='周杰伦'
    def inner():
        print(name)#在内层函数中,使用了外层函数的局部变量
    inner()
wrapper()
'''
结果:
周杰伦
'''

(2)

def wrapper():
    name='周杰伦'
    def inner():
        print(name)#在内层函数中,使用了外层函数的局部变量
    return inner    #返回函数名
ret=wrapper()
ret()

对比(1)和(2)的方式

闭包的优点:(定义:内层函数使用了外层函数的变量)

    1.可以保护变量不被其他人侵害

2.保持一个变量常驻于内存
(3)#注意下面的注释
def wrapper():
    name='周杰伦'
    def inner():
        print(name) #在内层函数中使用了外层函数的局部变量
    return inner    #返回函数名

ret=wrapper()  #ret是一个内层函数
ret()   #ret是inner,在外层执行的时机是不确定的,必须保证里面的name必须存在

(4)

#超级简易版爬虫
from urllib.request import urlopen #导入一个模块
def func():
    #获取到网页中的内容,
    content=urlopen('https://www.dytt8.net/').read()
    return content.decode('gbk')
print(func())

(5)#把要反复打开的网站加载 到内存中,以便快速打开网站,缺点:耗内存

#提升缓存能力版

#解决缓存问题
# #超级简易版爬虫
from urllib.request import urlopen #导入一个模块

#苹果系统:干掉数字签名
# import ssl
# ssl._create_default_https_context=ssl._create_unverified_context()

def func():
    #获取到网页中的内容,当网速很慢的时候,反复的去打开这个网站,很慢
    content=urlopen('https://www.dytt8.net/').read()
    def inner():
        return  content.decode("gbk") #网页内容
    return inner
    # return content.decode('gbk')
print('开始网络请求')
ret=func()      #网络请求已经完毕
print('网络请求完毕')
print('第一次',ret()[5])
print('第二次',ret()[5])

# print('第一次',ret())
# print('第二次',ret())
 

3.迭代器

(1)

s='今天下午考试'
for c in s:
    print(c)

#主要讨论:什么是可迭代,什么是不可迭代的?

'''

结果:






'''

(2)

for c in '哼哼哈哈':
    print(c)#正确

for c in 123:
    print(c)#错误

(3)

dir() 可以帮助我们查看xxx数据能够执行的操作
print(dir(str))     #__iter__
print(dir(int))     #没有__iter__
print(dir(list))     #有__iter__
print(dir(dict))     #有__iter__
print(dir(bool))     #没有__iter__

for i in True:
    print(i)            #报错:'bool' object is not iterable

(4)

print(dir(range))
f=open('呵呵',mode='r',encoding='utf-8')
print(dir(f))           #正确,文件也是可迭代的
共性:所有带有__iter__的东西都可以进行for循环,带有__iter__东西就是可迭代对象
(5)
lst=['贾樟柯','李安','杨德昌','王家卫']

# print('__iter__' in dir(lst))   #判断迭代器是否在lst中,结果:True
it=lst.__iter__()       #it是拿到的是迭代器
print(it)               #列表的迭代地址:<list_iterator object at 0x0000026309647518>

print(it.__next__()) #下一个
print(it.__next__()) #下一个
print(it.__next__()) #下一个
print(it.__next__()) #下一个

# print(it.__next__()) #报错:下一个报错,因为列表中只有4个值  StopIteration  停止迭代

it=lst.__iter__()    #只能重新获取迭代器
print(it.__next__()) #下一个,又可以用了
总结
1.只能向下执行,不能反复
2.结束的时候会给我们扔来一个错误 StopIteration
3.整合所有的数据类型进行遍历(int,bool除外)#最大的特点

(6)超级重点

lst=['海尔兄弟','阿童木','葫芦娃','舒克贝塔','大风车']
#while循环模拟for循环 for el in lst:
it=lst.__iter__()   #获取到迭代器0
while 1:    #循环
    try:    #尝试
        el=it.__next__()  #拿数据
        print(el)
    except StopIteration:   #出了错误,意味着数据拿完了
        break       #结束循环
总结:
1.节省内存
2.惰性机制
3.不能反复,只能向下执行
hello world!

(7)

官方通过代码判断是否是迭代器
借助于两个模块,Iterator迭代器,Iterable可迭代的
from collections import Iterator,Iterable
lst=[1,2,3]
print(isinstance(lst,Iterator)) #某某某是否是迭代器,False
print(isinstance(lst,Iterable)) #某某某是否是可迭代的类型,True

it=lst.__iter__()   #迭代器一定可迭代,可迭代的东西不一定是迭代器

print(isinstance(it,Iterator)) #某某某是否是迭代器,False
print(isinstance(it,Iterable)) #某某某是否是可迭代的类型,True

结果:

False
True
True
True

总结:有些地方还有待完善

猜你喜欢

转载自www.cnblogs.com/studybrother/p/10099977.html