1.函数名
一.函数名的运用
函数名是一个变量,但它是一个特殊的变量,与括号配合可以执行函数的变量
1.函数名的内存地址
def func(): print("呵呵") print(func) 结果: <function func at 0x1101e4ea0>
2.函数名可以赋值给其他变量
def func(): print("呵呵") print(func()) a = func #把函数当成一个变量赋值给另一个变量 a() #函数调用 func()
3.函数名可以当作容器类的元素
1 def func1(): 2 print("呵呵") 3 4 5 def func2(): 6 print("呵呵") 7 8 9 def func3(): 10 print("呵呵") 11 12 13 def func4(): 14 print("呵呵") 15 16 17 lst = [func1, func2, func3] 18 for i in lst: 19 i()
4.函数名可以当作函数的参数
1 def func(): 2 print("吃了吗") 3 4 5 def func2(fn): 6 print("我是func2") 7 fn() #执行传递过来的fn 8 print("我是func2") 9 10 11 func2(func) #把函数func当成参数传递给func2的参数fn
5.函数名可以作为函数的返回值
1 def func_1(): 2 print("这里是函数1") 3 4 def func_2(): 5 print("这里是函数2") 6 7 print("这里是函数1") 8 return func_2() 9 10 11 ret = func_1() #执行函数1,函数1返回的是函数2,这时ret指向的就是上面函数2 12 ret() #执行上面返回的函数 13
2.闭包
什么就是闭包?闭包就是内层函数,对外层函数(非全局)的变量的引用.叫闭包
def func1(): name = "alex" def func2(): print(name) # 闭包 func2() func1() 结果: alex
我们可以使用__closure__来检测函数是否是闭包.使用函数名.__closure__返回cell就是闭包,返回None就不是闭包
def func1(): name = "alex" def func2(): print(name) #闭包 func2() print(func2.__closure__) #(<cell at 0x0000019E0E3164C8: str object at 0x0000019E0E3A8148>,) func1()
问题,如何在函数外边调用内部函数
1 def outer(): 2 name = "alex" 3 4 # 内部函数 5 def inner(): 6 print(name) 7 8 return inner 9 10 11 ret = outer() #访问外部函数,获取到内部函数的函数地址 12 ret() #访问内部函数 13
那如果多层嵌套呢?很简单,只需要一层一层的往外返回就行了
1 def func1(): 2 def func2(): 3 def func3(): 4 print("嘿嘿") 5 6 return func3 7 8 return func2 9 10 11 func1()()()
好处:
保护变量
常驻内存
3.迭代器
1 # 对的 2 s = "abc" 3 for c in s: 4 print(c) 5 6 7 8 9 # 错的 10 for i in 123: 11 print(i) 12 13 14 15 结果: 16 Traceback (most recent call last): 17 File "F:/py/lianxi.py", line 26, in <module> 18 for i in 123: 19 TypeError: 'int' object is not iterable
注意看报错信息中有这样一句话:int object is not iterable 翻译就是整数类对象是不可迭代的iterable表示迭代的,表示可迭代协议.可通过dir函数查看类中定义好的所有方法
s = "红红火火恍恍惚惚" print(dir(s)) #可以打印对象中的方法和函数 print(dir(str)) #也可以打印类中声明的方法和函数
通过dir看所有方法中有__iter__函数,这些都还可以进行for循环
还可以通过isinstence()函数来查看一个对象是什么类型的
1 l = [1, 2, 3] 2 l_iter = l.__iter__() 3 from collections import Iterable 4 from collections import Iterator 5 6 print(isinstance(l, Iterable)) 7 print(isinstance(l, Iterator)) 8 print(isinstance(l_iter, Iterator)) 9 print(isinstance(l_iter, Iterable))
如果有__iter__函数的话,就是可迭代的,就可以获得相对应的迭代器,我们使用迭代器中的__next__()来获取
1 s = "北京欢迎你" 2 c = s.__iter__() #获取迭代器 3 print(c.__next__()) #使用迭代器进行迭代. 获取一个元素 北 4 print(c.__next__()) #京 5 print(c.__next__()) #欢 6 print(c.__next__()) #迎 7 print(c.__next__()) #你 8 print(c.__next__()) #StopIteration
for循环的机制:
1 for i in range(5): 2 print(i) 3 4 lst = [1,2,3,4,5] 5 it = lst.__iter__() 6 while 1: 7 try: 8 i = it.__next__() 9 excpet StopIteration: 10 break
小总结:
Iterable:可迭代对象.内部包含__iter__()函数
Iterator:迭代器.内部包含__iter__()同时包含__next__().
迭代器的特点:
1.节省内存
2.惰性机制
3.只能向前,(像时间)