1.第一类对象
函数名----->变量名
(1)函数对象可以像变量一样进行赋值.
def fn():
print("我叫fn")
gn=fn #函数名可以进行赋值
gn()
比较: fn=666
print fn
(2)可以像列表元素一样使用
def fun1():
print("朱祁镇")
def fun2():
print("徐阶")
def fun3():
print("王阳明")
lst=[func1,func2,func3]
print(lst)
一个函数: lst[0]()
那么循环: for el in lst: 注意:lst内部元素没有类型限制
el()
lst=[func1(),func2(),func3()]函数+()就是调用,返回列表是None.
(3) 函数名可以像返回值一样返回--------------导致在函数外面访问了函数内部的函数.
def wrapper():
def inner():
print("哈哈")
return inner
ret = wrapper()
ret() #在函数外面访问了函数内部函数
###思考### 与return inner() 有什么区别
(4)函数可以作为参数进行传递
(1) def func1():
print("谢晋")
def func2():
print("杨士奇")
def func3():
print("徐渭")
def proxy(a):##a就是变量,形参
a()
proxy(func1) ##func1函数名作为参数传递
proxy(func3)
(2)装饰器的雏形=代理模式
def proxy(a):##a就是变量,形参
print("代理开始")
a()
print("代理结束完毕")
2.闭包-------->函数的嵌套
内层函数对外层函数中的变量的使用.
def wrapper():
name="周杰伦"
def inner():
print(name) #在内层函数中使用了外层函数的局部变量
return inner 返回函数名
ret=wrapper()
ret()
回想全局变量,发现全局变量很不安全,甚至可以修改.
闭包的优点:(1)可以保护变量不被其他人侵害
(2) 保持一个变量常驻内存
def wrapper():
name="周杰伦" ###局部变量常驻内存
def inner():
print(name) #在内层函数中使用了外层函数的局部变量
return inner 返回函数名
ret=wrapper() ###ret是一个内层函数
ret() ##ret是inner,执行时间不确定,必须保证里面的name必须存在.
实例 :超级简易版爬虫
1 from urllib.request import urlopen # 导入一个模块 # 干掉数字签名 2 import ssl ssl._create_default_https_context = ssl._create_unverified_context 3 4 5 def func(): # 获取到网页中的内容, 当网速很慢的时候. 反复的去打开这个网站. 很慢 6 content = urlopen("https://www.dytt8.net/").read() 7 def inner(): 8 9 return content.decode("gbk") # 网页内容 10 return inner 11 12 13 print("开始网络请求") r 14 et = func() # 网络请求已经完毕 15 print("网络请求完毕") 16 print("第一次", ret()[5]) 17 print("第二次", ret()[5]) #
如何通过代码查看闭包
函数.__closure__ 来查看,用print(函数.__closure__ ).如果返回内容,则是闭包,如果返回None,则不是闭包.
def wrapper(): name = "alex" def inner(): print(name) print(inner.__closure__) # 查看是否是闭包. 有内容就是闭包, 没有内容就不是闭包 inner() wrapper()
返回
1 C:PythonPython37python.exe "F:/python_课程资料/老男孩/day11 第一类对象 闭包 迭代器/code/day11 第一类对象 闭包 迭代器/04 闭包.py" 2 (<cell at 0x0000000001DEC7C8: str object at 0x0000000001DC2F80>,) 3 alex 4 5 Process finished with exit code 0
如果不是闭包,如下:
def wrapper(): name = "alex" def inner(): print("baozi") print(inner.__closure__) # 查看是否是闭包. 有内容就是闭包, 没有内容就不是闭包 inner()
返回:
C:PythonPython37python.exe "F:/python_课程资料/老男孩/day11 第一类对象 闭包 迭代器/code/day11 第一类对象 闭包 迭代器/04 闭包.py"
None
baozi
Process finished with exit code 0
3. 迭代器
(1)查询某某对象是否是可迭代对象
iterable 可迭代的
通过dir() 可以帮助查看某某数据能够执行的操作,其中"__iter__"代表可以迭代.
经过试验,所有带有"__iter__"可以进行for循环,带有"__iter__"的数据类型就是可迭代对象.
str ,list,tuple,dict,句柄,range()都是可迭代对象;int,bool不可迭代.
(2) lterator -------迭代器
lst = ["贾樟柯", "李安", "杨德昌", "王家卫"] print("__iter__" in dir(lst)) it = lst.__iter__() # 拿到的是迭代器 <list_iterator object at 0x0000000001DCC160> print(it.__next__()) # 下一个 print(it.__next__()) # 下一个 print(it.__next__()) # 下一个 print(it.__next__()) # 下一个 print(it.__next__()) # 下一个 # StopIteration 停止迭代
迭代器特点:
1.节省内存----生成器
2.惰性机制
3. 只能向下执行,不能反复;
结束时会扔出一个错误 ------StopIteration
意义:整合所有的数据类型进行遍历(int,bool除外)
如果想重新再迭代,得再获取 迭代器.
it=lst.__iter__() ##重新获取迭代器.
理解::医生叫号模式,不排队的病人.
lst = ["海尔兄弟", "阿童木", "葫芦娃", "舒克贝塔", "大风车"] # 模拟for循环 for el in lst: it = lst.__iter__() # 获取到迭代器0 while 1: # 循环 try: # 尝试 el = it.__next__() # 那数据 print(el) except StopIteration: # 出了错误, 意味着数据拿完了 break # 结束循环
lst可是未知量的
4.(1)官方通过代码判断是否是迭代器
借助于两个两个模块.Iterator 迭代器,Iterable 可迭代的
from collections import Iterable,Iterator
lst=[1,2,3]
print (isinstance(你,树))#判断xxx是不是xx类型,false.
print (isinstance(lst,Iterable)) 判断lst是不是可迭代的,True
print (isinstance(lst,Iterator)) 判断lst是不是迭代器,false
it=lst.__iter__()
print (isinstance(lst,Iterable)) 判断it是不是可迭代的,True
print (isinstance(lst,Iterator)) 判断it是不是迭代器,True
得出结论:
迭代器一定可迭代,可迭代的东西不一定是迭代器.
for el in it :
print(el)
(2)野路子判断是否是迭代器
用dir()寻找其支持的操作:
__iter__ 可迭代的
__iter__ __next__ 迭代器(找到这两个操作就可以判断为是迭代器)
()