函数第一类对象,闭包,迭代器

一,函数名的运用:第一类对象

函数名是一个变量,但是一个特殊的变量,与括号配合可以执行函数的变量.

1.直接打印函数名就是个内存地址:

def func():
    print('哈哈')
print(func)
结果:<function func at 0x0000000000864488>

2.函数名可以赋值给其他变量

def func():
    print('哈哈')
ret = func  #把函数当成一个变量,赋值给另一个变量
ret()  #函数调用func()

3.函数名可以当做容器类的元素:

def func():
    print('哈哈')
def func1():
    print('呵呵')
def func2():
    print('嘿嘿')
def func3():
    print('嘻嘻')
lst = [func,func1,func2,func3]
for i in lst:
    i()
结果: 哈哈
     呵呵
     嘿嘿
     嘻嘻            

4,函数名可以当做函数的参数:

def func():
    print('哈哈')
def func1(fn): #func传递给fn
    print('呵呵')
    fn() # fn()变成了func() 所以在这里执行func()函数
    print('嘻嘻')
func1(func)

5.函数名可以作为函数的返回值

def func():
    print('哈哈')
    def func1():
        print('嘿嘿')
    print('呵呵')
    return func1
ret = func()  #执行func()函数,打印出'哈哈',这时候ret指向fun1
ret()#即func1(),执行func1函数

二.闭包

闭包就是内层函数对外层函数(非全局)的变量的引用.

def func():
    name = 'alex'
    def func1():
        print(name)
    func1()
func()
结果:alxe

__closure__检测函数是否是闭包,是返回cell,不是返回None.

def func():
    name = 'alex'
    def func1():
        print(name)
    func1()
    print(func1.__closure__)
func()
结果: alex (
<cell at 0x000000000121C078: str object at 0x0000000001202848>,)#是闭包

1.函数外面调用内部函数:

def func():
    name = 'alex'
    def func1():
        print(name)
    return func1
ret = func() #访问外部函数,获取内部函数的内存地址
ret()  #执行内部函数

2.多层嵌套:

def func1():
    def func2():
        def func3():
            print('嘿嘿')
        return func3
    return func2
func1()()()

闭包的作用:1.安全,不能从函数外部去修改函数内部的变量

     2.让一个变量常驻内存,供后边的程序使用,效率高

三.迭代器(Iterator)  可迭代对象:(Iterable)

可迭代对象:str list tuple dict set 文件句柄f .这些被称为可迭代对象,基于可迭代协议..

1,dir用法: 

s = '哈哈哈'
print(dir(s)) #可以打印对象中的方法和函数
print(dir(str)) #可以打印类中声明的方法和函数

用dir打印出来的结果如果能找到__iter__,那么这个类的对象就是一个可迭代对象.

经过dir查找,发现list,tuple,str,dict,set都有__iter__函数,range也有.这些都是可以用for循环的.

2.isinstence(对象,类型)判断xx对象是什么类型的

lst = [1,2,3]
from collections import Iterable
from collections import Iterator
print(isinstance(lst,Iterable))  #判断是否是可迭代对象
print(isinstance(lst,Iterator)   #判断是否是迭代器
结果:True
    False
lst = ['皇阿玛','皇后','皇太子']
it = lst.__iter__() #获取迭代器
from collections import Iterable
from collections import Iterator
print(isinstance(it,Iterable))
print(isinstance(it,Iterator))
结果:True
   True

结论:迭代器一定是可迭代的,但可迭代的不一点是迭代器

3.判断是否可迭代的方法:

s = '哈哈哈'
lst = [1,2,3]
i = 123
print('__iter__'in dir(s))   #True
print('__iter__'in dir(lst)) #True
print('__iter__'in dir(i))   #False

4.__next__()  获取迭代器的元素

lst = ['皇阿玛','皇后','皇太子']
it = lst.__iter__() #获取迭代器
print(it.__next__())
print(it.__next__())
print(it.__next__())

注意:如果有第四个print找不到就会报错

在迭代器中有__next__()和__iter__()函数

而在可迭代对象中只有__iter__()函数  所以要确定这个可迭代对象是否是迭代器可以看是否有__next__()

5.

f = open("01",mode="r", encoding="utf-8")
from collections import Iterable
from collections import Iterator
print(isinstance(f, Iterable))
print(isinstance(f, Iterator))
结果:True  #文件句柄既是可迭代对象有事迭代器
   True

6.使用while循环 +迭代器来模拟for循环

lst = [1,2,3]
lst_iter = lst.__iter__()
while True:
    try:
        it = lst_iter.__next__()
        print(it)
    except StopIteration:
        break

迭代器特点:

1.节省内存

2.惰性机制

3.不能反复,只能向下执行

posted on 2018-07-17 20:44  IT东  阅读(152)  评论(0编辑  收藏  举报

导航