一、第一类对象,函数名的使用
函数名就是变量名,函数名存储的是函数的内存地址,但它是一个特殊的变量,与括号配合可以执行函数的变量
变量的命名规范:https://www.cnblogs.com/minusone/p/9805946.html
1.函数名的内存地址
def func(): print("呵呵") print(func) 结果: <function func at 0x1101e4ea0>
2.函数可以赋值给其他变量
def func(): print("呵呵") print(func) a = func # 把函数当成一个变量赋值给另一个变量 a() # 函数调用 func()
3.函数名可以当做容器类的元素
def func1(): print("呵呵") def func2(): print("呵呵") def func3(): print("呵呵") def func4(): print("呵呵") lst = [func1, func2, func3] for i in lst: i()
4.函数名可以当做函数的参数
def func(): print("吃了么") def func2(fn): print("我是func2") fn() # 执行传递过来的fn print("我是func2") func2(func) # 把函数func当成参数传递给func2的参数fn.
5.函数名可以作为函数的返回值
def func_1(): print("这里是函数1") def func_2(): print("这里是函数2") print("这里是函数1") return func_2 fn = func_1() # 执行函数1. 函数1返回的是函数2, 这时fn指向的就是上面函数2 fn() # 执行上面返回的函数
6,
def panpan(): print("我是潘潘. 我喜欢毒丈夫 ") def xiaoping(): print("我是小萍萍. 我喜欢毒丈夫 ") def xiaohua(): print("我是小花花. 我喜欢毒丈夫 ") def daguanren(): print("大官人喜欢xxxx") def wangpo(nv, nan): # 核心业务逻辑 nv() nan() wangpo(xiaohua, daguanren) # 王婆代理了大官人和潘潘
7,还原真正的函数名
def chi(): print("我是吃") a = chi haha = a hehe = haha bilibili= hehe bilibili() print(bilibili.__name__) # 函数名
8,函数的注释
def play(wanjv1, wanjv2, wanjv3): ''' 玩儿函数 :param wanjv1: 玩具1 :param wanjv2: 玩具2 :param wanjv3: 玩具3 :return: 开心 ''' print("我要玩儿荡秋千") return "开心"
play("独木桥", "独轮车", "独眼龙")
print(play.__doc__) # document 可以打印出文档的注释
二、闭包
全局变量可能会被修改, 全局变量是不安全的. 可能会被其他函数所更改 a = 10 def func(): global a a = 20 print(a) func() print(a)
def func(): a = 10 print(a) func() print(a) # 在外面你是访问不到局部变量的, 局部变量是安全的
用闭包可以保护我们的变量 写法: 在外层函数中声明一个变量. 在内层函数使用或者返回这个变量. 这个结构叫闭包 1.可以保护我的变量 2.可以让一个变量常驻内存 def outer(): a = 10 # 常驻内存 def inner(): print(a) # 在内部使用的外面的变量 return inner # 返回了内部函数 # ret是inner的地址. ret就是inner ret = outer() ret() # 这里执行inner()
print("哈哈") print("哈哈") print("哈哈") ret() # inner的执行时间是不确定的 print("哈哈") print("哈哈") print("哈哈") ret() # inner的执行时间是不确定的 def haha(): pass print(ret.__closure__) # 有东西, 就是闭包. None就不是闭包
闭包的应用.保护变量, 常驻内存 from urllib.request import urlopen def func(): # 闭包. content会常驻内存 content = urlopen("http://www.xiaohuar.com/").read() def inner(): return content return inner print("加载中...") g = func() # 网络请求 print("加载完毕") print(g()) print(g()) print(g())
三、迭代器
dir() 查看变量能够执行的方法(函数)
Iterator:迭代器 如果方法中存在__iter__(),__next__()则为迭代器
Iterable:可迭代的 如果方法中存在__iter__(),则为可迭代对象
这是查看一个对象是否是可迭代对象的第一种方法,我们还可以通过isinstence()函数来查看一个对象是什么类型的
l = [1,2,3] l_iter = l.__iter__()
from collections import Iterable from collections import Iterator print(isinstance(l,Iterable)) #True print(isinstance(l,Iterator)) #False print(isinstance(l_iter,Iterator)) #True print(isinstance(l_iter,Iterable)) #True
for循环的机制:
for i in [1,2,3]: print(i)
使用while循环+迭代器来模拟for循环(必须要掌握)
lst = [1,2,3] l1 = lst.__iter__() while Ture: try: l2 = l1.__next__() print(l2) except StopIteration: break
从迭代器中获取数据的唯一方法:__next__()
迭代器的特点:
1.节省内存
2.惰性机制
3.不能反复,只能向下执行
我们可以把要迭代的内存当成子弹,然后呢,获取到迭代器__iter__(),就把子弹都装在弹夹中,然后发射就是__next__()把每一个子弹(元素)打出来,也就是说,for循环的时候,一开始的时候是__iter__()来获取迭代器,后面每次获取元素都是通过__next__()来完成的,当程序遇到StopIteration将结束循环。