1.函数名使用及第一类对象
函数名是一个变量, 但它是一个特殊的变量, 与括号配合可以执行函数的变量.
1.函数名的内存地址
def func(): print(1) print(func) #内存地址 <function func at 0x027B34B0>
2.函数名可以赋值给其他变量
def func(): print(1) a = func # 函数名当做值赋值给变量 a() func()
3.函数名可以当做参数去传递
def func(): return '大姑娘美' def func2(msg): # mag = func print(msg) # msg??? func内存地址 func2(func()) # 函数名可以当做参数去传递 注意点 传递函数名的时候如果+()就是在传递这个函数的返回值
4.函数名可以作为函数的返回值
def foo(): print(2) # 当函数没有写return默认返回None def func(msg): print(1) return msg print(func(foo)) # 函数名可以当做返回值被返回
5.函数名可以当做元素存放在一个容器当中
def func1(): print("哈哈") def func2(): print("呵呵") def func3(): print("嘿嘿") def func4(): print("哼哼") lst = [func1, func2, func3] # 函数名可以当做元素存放在一个容器当中 for i in lst: i()
2.闭包
闭包就是内层函数, 对外层函数(非全局)的变量的引用. 叫闭包
def func1(): name = "你好" def func2(): print(name) # 闭包 func2() func1() # 结果: 你好
使用函数名.__closure__来检测,返回cell就是闭包. 返回None就不是闭包
def func(): name = '宝元' def foo(): print(name) foo() print(foo.__closure__) # (<cell at 0x007C1370: str object at 0x007C45C0>,) func() print(func.__closure__) # 返回的结果不是None就是闭包
def outer(): name = "你好" # 内部函数 def inner(): print(name) return inner fn = outer() # 访问外部函数, 获取到内部函数的函数地址 fn() # 访问内部函数
多层嵌套中的使用:
def func1(): def func2(): def func3(): print("嘿嘿") return func3 return func2 func1()()()
嵌套函数,在嵌套函数内,内部函数使用外部变量(非全局变量) 就是一个闭包 闭包可以多层。
闭包的好处:
1.保护变量不会被外界修改
2.函数内使用到的变量会生命周期延长
3.节省开辟空间和销毁空间的时间
3.迭代器
遵守迭代协议(标准):
1.遵守迭代器的协议 具有__iter__()方法和__next__()方法
2.可以被for循环的就是可迭代对象(除去int和bool,str,list,tuple,dict,set,range()这些都是可迭代)
print(dir(str)) # 查看这个类型中有什么功能 可迭代__iter__
#查看是迭代器还是可迭代对象: from collections import Iterator,Iterable print(isinstance('查看的内容',Iterable)) # 查看是否是可迭代的 print(isinstance('查看的内容',Iterator)) # 查看是否是迭代器 # 迭代器一定是可迭代的,但是可迭代的不一定是迭代器
如果对象中有__iter__函数,那么我们认为这个对象遵守了可迭代协议.就可以获取到相应的迭代器。
lst = [1,2,3,4,5,6] l = lst.__iter__() # 从一个可跌代对象转换成迭代器 print(l.__next__()) print(l.__next__()) print(l.__next__()) print(l.__next__()) print(l.__next__()) print(l.__next__()) print(l.__next__())
for循环的机制
lst = [1,2,3,4,5] #第一种 count = 0 l = lst.__iter__() while count < len(lst): print(l.__next__()) count += 1 #第二种 lst = [1,2,3,4,5,67,7] l = lst.__iter__() while True: try: # 异常捕获 print(l.__next__()) except StopIteration: break
注意: 迭代器不能反复,只能向下执行
总结:
Iterable: 可迭代对象. 内部包含__iter__()函数
Iterator: 迭代器. 内部包含__iter__() 同时包含__next__().
迭代器的特点:
1. 节省内存.
2. 惰性机制
3. 不能反复, 只能向下执行.
4. 一次性的