函数名的应用,闭包,迭代器

函数名的应用

函数名其实就是一个变量,命名规范和变量一样

变量可以做的,函数名也可以做

a = 10
b = a # 赋值操作
print(b) # 变量a的值赋给了b,所以b=10

def func():
    print("我是一个小小的函数")
a = func #函数名赋给了a
print(a) # a就是func,所以如果想要调用函数就可以写成 a()
a()     #我是一个小小的函数
func() #我是一个小小的函数
#以上 a和func的作用是一样的

#也可以拿来做变量可以做的事,比如for遍历
def func1():
    print("我是1")
def func2():
    print("我是2")
def func3():
    print("我是3")

lst = [func1, func2, func3]
for el in lst:
    el() >>>#el就是列表中每个函数名所以结果就是依次调用函数
#结果:
我是1
我是2
我是3

闭包

在内层函数中访问外曾函数的变量

作用:

  • 保护内层函数变量不受侵害,更为安全
  • 变量在执行结束的时候不会被清空,变量常驻内存,可以随时取用
#闭包写法:
def outer():
    a = 10
    def inner():
         print(a)
    return inner
 #这就是一个闭包,变量a只能在局部范围使用

迭代器

可迭代对象

现在有一数据,我们可以用dir来查看该数据包含了哪些处理方法,也就是说该数据支持什么处理方式

#字符串
print(dir(str))
>>>
['__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']

#列表
print(dir(list))
>>>
['__add__', '__class__', '__contains__', '__delattr__', '__delitem__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__getitem__', '__gt__', '__hash__', '__iadd__', '__imul__', '__init__', '__init_subclass__', '__iter__', '__le__', '__len__', '__lt__', '__mul__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__reversed__', '__rmul__', '__setattr__', '__setitem__', '__sizeof__', '__str__', '__subclasshook__', 'append', 'clear', 'copy', 'count', 'extend', 'index', 'insert', 'pop', 'remove', 'reverse', 'sort']

#int
print(dir(int))
>>>
['__abs__', '__add__', '__and__', '__bool__', '__ceil__', '__class__', '__delattr__', '__dir__', '__divmod__', '__doc__', '__eq__', '__float__', '__floor__', '__floordiv__', '__format__', '__ge__', '__getattribute__', '__getnewargs__', '__gt__', '__hash__', '__index__', '__init__', '__init_subclass__', '__int__', '__invert__', '__le__', '__lshift__', '__lt__', '__mod__', '__mul__', '__ne__', '__neg__', '__new__', '__or__', '__pos__', '__pow__', '__radd__', '__rand__', '__rdivmod__', '__reduce__', '__reduce_ex__', '__repr__', '__rfloordiv__', '__rlshift__', '__rmod__', '__rmul__', '__ror__', '__round__', '__rpow__', '__rrshift__', '__rshift__', '__rsub__', '__rtruediv__', '__rxor__', '__setattr__', '__sizeof__', '__str__', '__sub__', '__subclasshook__', '__truediv__', '__trunc__', '__xor__', 'bit_length', 'conjugate', 'denominator', 'from_bytes', 'imag', 'numerator', 'real', 'to_bytes']

#我们知道字符串和列表是支持for 循环的,也就是可迭代的,但是int不是可迭代的,你们发现了什么呢?
#列表和字符串中都有一个相同的东西 __iter__,而int没有,那我们可以认为,可迭代对象中都有这个__iter__

获取迭代器

#有了可迭代对象,我们就可以用for循环了,那么在程序内部for循环是怎么运行的呢?
#可迭代对象可以使用__iter__获得迭代器
s = "周杰伦喜欢昆凌"
it = s.__iter__() # 获取迭代器
print(dir(it)) 
>>>
['__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__']


lst = [1,2,3,4,5,6,7,8]
li = lst.__ister__() #获取迭代器
print(dir(li))
>>>
['__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__']

#生成的迭代器找那个都有个 __next__,类似于喊号,下一个的作用

官方判断数据是否是可迭代的,以及数据是否可以生成迭代器的方法

#引入模块
from collections import Iterable  # 可迭代对象
from collections import Iterator    # 迭代器

print(isinstance(lst, Iterable)) #对象是否可迭代
print(isinstance(lst, Iterator))#可否生成迭代器

print(isinstance(it, Iterable))
print(isinstance(it, Iterator))

小结:

可迭代对象:Iterable, 里面有__iter__()可以获取迭代器, 没有__next__()

迭代器:Iterator, 里面有__iter__()可以获取迭代器, 还有__next__()

迭代器特点:

  • 只能向前.
  • 惰性机制.
  • 省内存(生成器)

for循环的内部机制.

  1. 首先获取到迭代器.
  2. 使用while循环获取数据
  3. it.__next__()来获取数据
  4. 处理异常 try:xxx   except StopIteration:
lst = ["周杰伦", "昆凌", "林俊杰", "姚明","潘长江"]
it = lst.__iter__() # 获取迭代器
while 1:
    try:    # 尝试执行
        el = it.__next__()  # 获取下一个元素
        print(el)
    except StopIteration:   # 处理错误
        break
>>>
周杰伦
昆凌
林俊杰
姚明
潘长江
#如果不写 except StopIteration: 虽不影响效果,但会则会报一个StopIteration(停止迭代)的错误

猜你喜欢

转载自www.cnblogs.com/--kai/p/9455879.html