函数 名的使用和第一类对象,闭包,迭代器
1,函数名的运用:
- 函数名(func())是一个变量,和变量由相同点和异同点,相同点:变量的命名规则同样适用于函数名,同样能进行赋值操作,异同点:函数名不能进行逻辑运算.
- 1>函数名的内存地址,函数名是有内存地址的,用print(func)可以查找出来
def func(): print("呵呵") print(func) # <function func at 0x000001532CC83158> a = 10 print(id(a)) # 1402039600
- 二者在查找内存地址的时候变量需要引入id()内置函数,而函数在查找的时候不用
- 2>函数名可以复制给其他变量,可以进行赋值操作
def func(): print("哈哈") a = func # 把函数名赋值给变量a a() # a现在是一个函数名,当加()表示执行函数
- 3>函数可以当容器类的元素,其实函数名就相当于一个句柄(自己理解)它把函数里边的东西封装起来,打包放在一个地方,函数名就行是一个药引子,当用的时候才会被调用(加(),)
# 函数名可以存放到容器中 def func1(): print("哈哈") def func2(): print("呵呵") def func3(): print("啊啊") def func4(): print("嗯嗯") lst = [func1, func2, func3, func4] for i in lst: i() # 分别执行函数
- 4>函数名可以当做函数的参数(实参),很灵活.
def func(): print("呵呵呵") def func1(fn): # 调用函数func1() print("哈哈哈") # 打印"哈哈哈" fn() # 此时运行的fn = func(),当fn(),其实就是调用你func函数 func1(func) # 运行结果是 哈哈哈 呵呵呵
- 5>函数名可以当做函数的返回值, return func
def func_1(): print("这里是函数1") def func_2(): print("这里是函数2") print("这里是函数1") # 第二步打印的是"这里是函数1" return func_2 # 返回func_2,西施返回的是一个函数名(无任何意义),只是返回一个值 fn = func_1() # 第一步:先执行函数func_1(),打印"这里是函数1", 在执行func_2赋值给fn fn() # 第五步,在fn后边加(),其实就是在func_2后边加(), 即是在调用函数func_2
2,闭包:闭包就是内层函数对外层函数的(非全局)变量的引用,叫做闭包,有点类似于nonlocal.
def func(): name = "alex" # 常驻内存,防止其他程序改变这个变量 def inner(): print(name) # 内层函数inner访问外部函数的变量 return inner # 返回inner这个函数名(并且是谁调用这个函数,就返回给谁) ret = func() ret() # 调用inner函数 # 列如: name = "wusir" # 把变量写在全局是极其不安全的,因为是谁都可以改变 def adc(): global name # 把全局变量弄到局部来 name = "呵呵" print(name) adc()
- 我们可以用 .__closure__来判断此函数是不是闭包
def func1(): name = "alex" def func2(): print(name) # 闭包 func2() print(func2.__closure__) # (<cell at 0x0000015C28358D38: str object at 0x0000015C2824C0D8>,)元组形式的内存地址 # 如果不是就返回None func1()
- 2.1>外层函数调用内层函数:先拿到内层函数的地址(内层函数的函数名),在调用内层函数
def outer(): name = "alex" # 内部函数 def inner(): print(name) return inner fn = outer() # 访问外部函数,获取到外部函数的内存地址 fn() # 访问内部函数
- 闭包的好处:
- 1>常驻内存
- 2>防止其他程序对内层函数变量改变
3,迭代器:迭代器就相当于引擎,为循环提供动力.
- 可迭代对象:str,list,dict,set,tuple
- 迭代器:句柄 f.
- 可迭代的对象(Iterable):内部包含 .__iter__().因此可以用 .__iter__()来判断这个对象是不是可迭代.
- 迭代器(Iterator):内部包含有 .__iter__() 和 .__next__()
s = "asdfg" print("__iter__" in dirs(s)) # True, 说明s是可迭代的 print(dir(s)) # 是判断s里面所有的内容
- ****模拟for循环:
lst = ["皇阿玛", "皇额娘", "容么么", "紫薇"] it = lst.__iter__() # 获取迭代器 while 1: # while循环,是把lst中的每一项都循环出来 try: # 尝试 name = it.__next__() # 去拿下一项 except StopIteration # 那不到数据的时候 break # 终止循环(只有循环的时候才break用)
- #isinstance(对象,类型) 判断***对象是否是***类型的
print(isinstance(lst.iterable)) # True,判断是否是可迭代的迭代器一定是可迭代的,可迭代的不一定是迭代器 print(isinstance(lst.iterable)) # False,迭代器里边有__next__().__iter__() print("__iter__" in dir(lst)) # 确定是一个可迭代对象 print("__next__" in dir(lst)) # 确定不是一个迭代器(如果一个对象里边包含__next__就说明是迭代器)
- **#迭代器的特点:
- 1>节省内存
- 2>惰性机制
- 3>只能往前拿,不能反着拿
lst = ["哈哈", "呵呵"] it = lst.__iter__() # 确定类lst是一个可迭代对象 it.__next__() # 确定lst里边包含__next__ print(it.__next__()) # 开始往出拿元素 print("我要吃黄瓜") print(it.__next__()) # 开始往出拿第二个元素
浙公网安备 33010602011771号