# 在函数中如果默认值参数是一个可变的数据类型, 如果有人调用的时候改变了他. 其他位置看到的也跟着改变了 def fn(val,list=[]): list.append(val) return list print(fn(5)) # 这个位置我们给val传值了打印的结果一定是[5] print(fn(6)) # 这个位置我们继续传值发现结果是[5, 6],那么也就是说函数中参数的默认值是同一个,而不是每次调用函数生产新的默认值
# # 在函数中如果默认值参数是一个可变的数据类型, 如果有人调用的时候改变了他. 其他位置看到的也跟着改变了 # def fn(val,list=[]): # list.append(val) # return list # # print(fn(5)) # # 这个位置我们给val传值了打印的结果一定是[5] # # print(fn(6)) # 这个位置我们继续传值发现结果是[5, 6],那么也就是说函数中参数的默认值是同一个,而不是每次调用函数生产新的默认值 # 什么是闭包以及闭包实际作用 # 我们知道函数声明的时候是不执行的,只有在调用的时候才会在内存开辟空间,python内部的垃圾回收机制,会在函数执行完毕后回收这块内存 def fn1(): val = 100 print(val) fn1() # 这个时候在执行完fn1后,它所在的那块内存就会被清空,而闭包的作用就是可以让这块内存常驻 def fn2(): val = 100 def fn3(): return val print(fn1.__closure__) print(fn2.__closure__) print(fn3.__closure__) return fn3 print(fn2()()) # 可以用__closure__函数来检测是不是闭包 # None # None # (<cell at 0x000001366E928B28: int object at 0x00007FFAD5407D60>,) fn3的结果是闭包 # 在python中srt,list,tuple,dict,set,file这些都属于可迭代对象,那么他们为什么是可迭代对象呢,因为它们遵循了可迭代协议 s = "真相定论" # print(dir(s)) # [‘__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‘] # 我们发现字符串中有__iter__这个就是迭代器,而拥有迭代器的则是可迭代对象` # print(dir(s.__iter__())) # [‘__class__‘, ‘__delattr__‘, ‘__dir__‘, ‘__doc__‘, ‘__eq__‘, ‘__format__‘, ‘__ge__‘, ‘__getattribute__‘, ‘__gt__‘, ‘__hash__‘, ‘__init__‘, ‘__init_subclass__‘, # ‘__iter__‘, ‘__le__‘, ‘__length_hint__‘, ‘__lt__‘, ‘__ne__‘, ‘__new__‘, ‘__next__‘, ‘__reduce__‘, ‘__reduce_ex__‘, ‘__repr__‘, ‘__setattr__‘, ‘__setstate__‘, # ‘__sizeof__‘, ‘__str__‘, ‘__subclasshook__‘] # 当我们执行它获取迭代器时,发现迭代器中也含有iter也是可迭代对象 itr = s.__iter__() # 获取迭代器 print(itr.__next__()) print(itr.__next__()) print(itr.__next__()) print(itr.__next__()) # 真 # # 相 # # 定 # # 论 # 分别打印出了四个字 lst = [1,2,3,4,5] itr2 = lst.__iter__() print(itr2.__next__()) print(itr2.__next__()) print(itr2.__next__()) print(itr2.__next__()) print(itr2.__next__()) # 获取lst的迭代器并且利用nextAPI实现了手动迭代
# 用while模拟一下迭代器 while 1: try: name = itr2.__next__() print(name) except StopIteration: break # try跟js中的容错机制差不多 # 还用一种判断是否为迭代器的方法 from collections.abc import Iterable from collections.abc import Iterator print(isinstance(itr,Iterable)) print(isinstance(itr,Iterator)) # True # True # 两个True所以itr即是迭代器又是可迭代对象 print(isinstance(lst,Iterable)) print(isinstance(lst,Iterator)) # lst是可迭代对象但不是迭代器
原文地址:https://www.cnblogs.com/tengx/p/11671036.html
时间: 2024-11-09 23:09:03