欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

漫步人生路之Python旅途(九)百日筑基

程序员文章站 2022-05-14 11:00:44
函数名的使用: 函数名可以作为值,赋值给变量 函数名可以作为参数传参给函数. 函数名可以作为返回值 函数名可以作为元素存储在容器里 闭包:在嵌套函数内,使用外层局部变量(非全局变量)就是一个闭包,闭包可以多层嵌套.闭包的优点: 避免局部变量不被外界修改 函数生命周期延长 节省开辟空间,销毁空间的时间 ......

函数名的使用:

  • 函数名可以作为值,赋值给变量
  • 函数名可以作为参数传参给函数.
  • 函数名可以作为返回值
  • 函数名可以作为元素存储在容器里

闭包:
在嵌套函数内,使用外层局部变量(非全局变量)就是一个闭包,闭包可以多层嵌套.
闭包的优点:

  • 避免局部变量不被外界修改
  • 函数生命周期延长
  • 节省开辟空间,销毁空间的时间

闭包的作用:就是使一个局部变量常驻内存,方便后面程序调用
如何查看一个函数是否是一个闭包
__closure__:查看一个函数是否是闭包

def func1():
    str_ = "闭包" # 局部变量
    def func2():
        print(str_) # 使用局部变量,闭包
    func2()
    print("fun2",func2.__closure__) # 打印func2是否是闭包
func1()
print("fun1",func1.__closure__)

#打印内容如下:
闭包 
fun2 (<cell at 0x000000000222d7c8: str object at 0x000000000224e0e0>,)
fun1 none     

通过打印可以看出fun2是闭包,
闭包的调用:

def func1():
    str_ = "闭包" # 局部变量
    def func2():
        print(str_) # 使用局部变量,闭包
    print(func2.__closure__) # 打印func2是否是闭包
    return func2
func1()() # 调用闭包func2()

# 打印内容如下:
(<cell at 0x00000000022ed7c8: str object at 0x0000000002431030>,)
闭包     


迭代器:
iterable表示可迭代的对象.遵守可迭代协议 使用dir(对象)可以查看数据类型是否符合可迭代协议.dir(对象)可以获取对象所有的方法,如果方法中有__iter__说明对象遵守可迭代协议,是可迭代类型数据.如下:

s = "hello world"
print(dir(s))

#打印内容如下:
'__init_subclass__', '__iter__', '__le__', ' # 这里只打印部分内容

还可以通过isinstance(对象,参数)来检测是可迭代对象还是迭代器.如果返回结果为true是可迭代对象,如果false不是可迭代对象.下面是对常见数据类型的打印:

num = 10
bool_t = true
str_1 = "hello world"
list_1 = [1,2,3]
tuple_1 = (1,2,3)
dict_1 = {"电影":"黄飞鸿","电视剧":"上海滩"}
set_1 = {1,2,3,4}
from collections.abc import iterable
print("int:",isinstance(num,iterable))
print("str:",isinstance(str_1,iterable))
print("bool:",isinstance(bool_t,iterable))
print("list:",isinstance(list_1,iterable))
print("tuple:",isinstance(tuple_1,iterable))
print("dict:",isinstance(dict_1,iterable))
print("set:",isinstance(set_1,iterable)) 
print("range:",isinstance(range(10),iterable)) 

#打印结果如下
int: false 
str: true 
bool: false 
list: true 
tuple: true 
dict: true 
set: true 
range: true 

由此可以得出,可迭代对象:有str,list,dict,set,tuple,range()
迭代器:如果可迭代对象中有__iter__函数就可以理解为是遵守可迭代协议的,那么这个可迭代对象就可使用__iter__以创建一个迭代器对象.在迭代器中可以使用__next__方法来获取所有迭代器中的元素.如下:

str_1 = "hello world"
from collections.abc import iterable,iterator
print(isinstance(str_1,iterator)) # 查看是否是迭代器
str_iter = str_1.__iter__() # 创建迭代器
print(isinstance(str_iter,iterator)) # 查看是否是迭代器

#打印结果如下:
false 
true 

由此可以证明上面的结论,可迭代对象通过__iter__方法创建迭代器.
for循环的工作原理就是通过迭代器来实现的.
下面来看个简单的迭代器

str_1 = "hello" 
str_iter = str_1.__iter__()
print(str_iter.__next__())
print(str_iter.__next__())
print(str_iter.__next__())
print(str_iter.__next__())
print(str_iter.__next__())

#打印内容如下:
h 
e 
l 
l 
o 

由上面的输出可以看出与for循环的输出类似.并且迭代器是不可回退的.但是当我们的迭代器超过字符串的长度后会报错stopiteration,那在使用for循环时for是怎么知道对象的长度,并且不会报错的呢?
下面我们用while循环和迭代器模拟for循环的内部机制.

str_1 = "hello"
str_iter = str_1.__iter__()
while true:
try: # 捕获异常
print(str_iter.__next__()) # 打印迭代器内容
except stopiteration: # 处理异常
break

#打印内容如下:
h 
e 
l 
l 
o 

注意:迭代器只能向下执行是不能回退的.
总结:
iterable: 可迭代对象. 内部包含__iter__()函数
iterator: 迭代器. 内部包含__iter__() 同时包含__next__().
迭代器的特点:

  • 节省内存.
  • 惰性机制
  • 不能反复, 只能向下执行.