函数名的应用
1 ,函数名就是函数的内存地址。
def func(): print(666) print(func) #<function func at 0x000001E82CF4C1E0>
2, 函数名可以作为变量。
a = 2 b = a c = b print(c) #2 def func1(): print(666) f1 = func1 f2 = f1 f2() #666

3,函数名可以作为函数的参数。
def func(): print('in func') def func1(): func() print('in func1') def func2(x): x() # func1() print('in func2') func2(func1)
""" in func in func1 in func2 """
4.函数名可以当做函数的返回值。
def wraaper(): def inner(): print('inner ') return inner ret = wraaper() # inner ret() # inner() #inner
def func2(): print('in func2') def func3(x): # x = func2 print('in func3') return x # func2 f1 = func3(func2) # func2 f1() """ in func3 in func2 """
5.函数名可以作为容器类类型的元素。
a = 6 b = 4 c = 5 l1 = [a,b,c] print(l1) #[6, 4, 5]
def func1(): print('in func1') def func2(): print('in func2') def func3(): print('in func3') def func4(): print('in func4') l1 = [func1,func2,func3,func4] for i in l1: i() """ in func1 in func2 in func3 in func4 """
向上面的函数名这种,第一类对象。
第一对象(first—class object) 指 1.可在运行期创建 2.可用作函数参数或者返回值 3.可存入变量的实体
*不明白? 那就记着一句话,就当普通变量用
闭包
内层函数对外层函数的变量(非全局变量)的引用,并且将函数名返回 这样就形成了闭包。
def wraaper(): name = 'alex' def inner(): print(name) print(inner.__closure__) inner() return inner wraaper() """ (<cell at 0x000001D3FEA60738: str object at 0x000001D3FE607880>,) alex """
name = 'alex' def wraaper(): def inner(): print(name) print(inner.__closure__) # None inner() return inner wraaper() """ None alex """ 非全局变量的引用
name = 'alex' def wraaper(n): n = 'alex' #此行是wraaper的name传给了n,相当于内部有个 n=‘alex’ def inner(): print(n) print(inner.__closure__) # cell at 0x000002AD93BF76D8: inner() return inner wraaper(name) """ (<cell at 0x0000027EC2BC0738: str object at 0x0000027EC2ADDAB0>,) alex """
__closure__此非判断函数是否闭包,按定义来判断准确。(必须返回函数名才是闭包,此方法不包括返回,所以不是判断条件。)
闭包作用:
当程序执行时,遇到了函数执行,他会在内存中开辟一个空间,局部名称空间,
如果这个函数内部形成了闭包,
那么他就不会随着函数的结束而消失。
from urllib.request import urlopen def index(): url = "http://www.xiaohua100.cn/index.html" def get(): return urlopen(url).read() return get xiaohua = index() # get content = xiaohua() # get() print(content.decode('utf-8'))
有了闭包的,那么这个get()函数不会随着函数结束而结束 ,就不会重复生成占用内存,这样就可以节省内存,无线使用。
迭代器
可迭代对象
for i in 'abc': print(i) """ a b c """
for i in 123: print(i) # 'int' object is not iterable
# 对象内部含有__iter__方法就是可迭代对象.
# 可迭代对象满足可迭代协议。
可迭代对象:str list dict,tuple,set,range()
s1 = 'strs' print(dir(s1)) #['__add__', '__class__', '__contains__', '__delattr__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__getitem__', '__getnewargs__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__iter__', '__le__', '__len__', '__lt__', '__mod__', '__mul__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__rmod__', '__rmul__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', 'capitalize', 'casefold', 'center', 'count', 'encode', 'endswith', 'expandtabs', 'find', 'format', 'format_map', 'index', 'isalnum', 'isalpha', 'isascii', 'isdecimal', 'isdigit', 'isidentifier', 'islower', 'isnumeric', 'isprintable', 'isspace', 'istitle', 'isupper', 'join', 'ljust', 'lower', 'lstrip', 'maketrans', 'partition', 'replace', 'rfind', 'rindex', 'rjust', 'rpartition', 'rsplit', 'rstrip', 'split', 'splitlines', 'startswith', 'strip', 'swapcase', 'title', 'translate', 'upper', 'zfill']
判断一个对象是否是可迭代对象:
第一个方法
s1 = 'strs' dic = {'name':'alex'} print('__iter__' in dir(s1)) #True print('__iter__' in dir(dic)) #True
第二种方法
from collections import Iterable # from collections import Iterator print(isinstance('alex',Iterable)) # True 可迭代对象成立否 print(isinstance('alex',Iterator)) # False 迭代器成立否 print(isinstance('alex',str)) # True 判断类型
迭代器
对象内部含有__iter__方法且含有__next__方法就是迭代器.
f = open('register', encoding='utf-8') print('__iter__' in dir(f)) #True print('__next__' in dir(f)) #True print('__iter__' in dir(dict)) #True print('__next__' in dir(dict)) #False
可迭代对象vs迭代器
可迭代对象不能取值,迭代器是可以取值的。
可迭代对象 --->(转化成)迭代器
lis = [1, 2, 3] # 可迭代对象 # ite1 = lis.__iter__() # 迭代器 <list_iterator object at 0x0000027A183BFFD0> 通过这样转换成迭代器 ite1 = iter(lis) # 迭代器 <list_iterator object at 0x0000027A183BFFD0> print(ite1) # <list_iterator object at 0x0000027A183BFFD0>
迭代器如何取值? next一次,取一个值
print(ite1.__next__()) print(ite1.__next__()) print(ite1.__next__()) print(ite1.__next__()),超出取值范围就报错。
__iter__ iter() 他们都是一个,只不过是包装成了内置函数。
__next__ next() 他们都是一个,只不过是包装成了内置函数。
特点:
1, 可迭代对象不能取值,迭代器是可以取值的。
2, 迭代器非常节省内存。每次只在内存中只占一个
3,迭代器每次只会取一个值。
4,,迭代器单向的,一条路走到头。
什么时候使用:数据量非常大,且只为了取值。
s1 = 'kfdsjl' # for i in s1: # print(i)
while 循环模拟for循环机制
1,将可迭代对象转化成迭代器。 2,调用__next__方法取值。 3,利用异常处理停止报错。 iter1 = s1.__iter__()
s1 = 'kfdsjl' iter1 = s1.__iter__() while 1: try: print(iter1.__next__()) except StopIteration: break """ k f d s j l """
作业
11,写函数,传入一个参数n,返回n的阶乘
例如:cal(7) 计算7*6*5*4*3*2*1
7+6+...+1 def sum1(n): s = 0 for i in range(n,0,-1): s = s + i return s print(sum1(8)) #推到 def sum1(n): s = 1 for i in range(n,0,-1): s = s * i return s print(sum1(8))

12写函数,返回一个扑克牌列表,里面有52项,每一项是一个元组(升级题)
例如:[(‘红心’,2),(‘草花’,2), …(‘黑桃’,‘A’)]
[(‘红心’,2),(‘草花’,2), …(‘黑桃’,‘A’)] def poker(argv): l1 = [] for num in range(1,14): for i in argv: l1.append((i,num)) return l1 print(poker(['黑桃','红心', '草花', '方块']))
13. def calc(a,b,c,d=1,e=2):
return a+b+c+d+e
# 请分别写出下列标号代码的输出结果,如果出错请写出Error。
print(calc(1,2,3,4,5)) # 15 print(calc(1,2)) # 报错 位置参数一一对应 print(calc(e=4,c=5,a=2,b=3)) # 15 print(calc(1,2,3)) # 9 print(calc(1,2,3,e=4)) # 11 print(calc(1,2,3,d=5,4)) # 15 def extendList(val,list=[]): list.append(val) return list list1 = extendList(10) # [10,] list list2 = extendList(123,[]) # [123.] list3 = extendList('a') # [10,'a'] list print('list1=%s'%list1) # [10,'a'] print('list2=%s'%list2) # [123.] print('list3=%s'%list3) # [10,'a'] list def extendList(val,list=[]): list.append(val) return list list1 = extendList(10) print('list1=%s'%list1) # [10,] list2 = extendList(123,[]) print('list2=%s'%list2) # [123,] list3 = extendList('a') print('list3=%s'%list3) # ['a'] [10,'a']

动态参数,当时讲有个坑,只要使用默认的参数,那么在内存中使用的就是一个。
ps:部分内容来自于互联网整理,如有侵权请联系我们,我们会在看到通知后24小时内做出处理。
posted on
浙公网安备 33010602011771号