迭代器

一. 函数名的应用, 第一类对象

1. 函数名的内存地址

def func():
    print("呵呵")
print(func)
结果:
<function func at 0x1101e4ea0>

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

def func():
    print('呵呵')
print(func)
a = func
print(a)
a()

结果:
<function func at 0x000001F8F1FC0158>
<function func at 0x000001F8F1FC0158>
呵呵

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

def func1():
    print('呵呵')
def func2():
    print('呵呵')
def func3():
    print('呵呵')
def func4():
    print('呵呵')
list = [func1,func2,func3,func4]
for el in list:
    el()
结果:
呵呵
呵呵
呵呵
呵呵

4.函数名可以当做函数的参数

def func():
    print("吃了么")
def func2(fn):
    print("我是func2")
    fn() # 执⾏传递过来的fn
    print("我是func2")
func2(func)    # 把函数func当成参数传递给func2的参数fn.
结果:
我是func2
吃了么
我是func2

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

def func_1():
    print("这⾥是函数1")
    def func_2():
        print("这⾥是函数2")
    print("这⾥是函数1")
    return func_2
fn = func_1() # 执⾏函数1. 函数1返回的是函数2, 这时fn指向的就是上⾯函数2
fn()
结果为:
这⾥是函数1
这⾥是函数1
这⾥是函数2

⼆. 闭包 什么是闭包? 闭包就是内层函数, 对外层函数(非全局)的变量的引⽤. 叫闭包

def func1():
    name = "alex"
    def func2():
        print(name) # 闭包
    func2()
func1()
结果:
alex

我们可以使⽤__closure__来检测函数是否是闭包. 使⽤函数名.__closure__返回cell就是 闭包. 返回None就不是闭包

def func1():
    name = "alex"
    def func2():
        print(name) # 闭包
    func2()
    print(func2.__closure__) # (<cell at 0x10c2e20a8: str object at 0x10c3fc650>,)
func1()

问题, 如何在函数外边调⽤内部函数呢?

def outer():
    name = "alex"
     # 内部函数
    def inner():
        print(name)
     return inner   
fn = outer()   # 访问外部函数, 获取到内部函数的函数地址
fn()   # 访问内部函数    

那如果多层嵌套呢? 很简单, 只需要⼀层⼀层的往外层返回就⾏了

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

三. 迭代器

⽬前我们所熟知的可迭代对象有: str, list, tuple, dict, set    所有的以上数据类型中都有一个函数__iter__(), 所有包含了__iter__()的数据类型都是可迭代的数据类型 Iterable

# 对的
s = "abc"
for c in s:
    print(c)
# 错的
for i in 123:
    print(i)

在打印结果中. 寻找__iter__ 如果能找到. 那么这个类的对象就是⼀个可迭代对象.

# dir()来查看一个对象,数据类型中包含了哪些东西
lst = [1,2,3]   # list
print(dir(lst))
结果为:
['__add__', '__class__', '__contains__', '__delattr__', '__delitem__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__getitem__', '__gt__', '__hash__', '__iadd__', '__imul__', '__init__', '__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']



s = "王尼玛"
print("__iter__" in dir(s))  # True

lst = [1,2,3]   # list
print("__iter__" in dir(lst))  #True

这是查看⼀个对象是否是可迭代对象的第⼀种办法. 我们还可以通过isinstence()函数来查 看⼀个对象是什么类型的

l = [1,2,3]
l_iter = l.__iter__()
from collections import Iterable
from collections import Iterator
print(isinstance(l,Iterable)) #True
print(isinstance(l,Iterator)) #False
print(isinstance(l_iter,Iterator)) #True
print(isinstance(l_iter,Iterable)) #True
s = "我爱北京天安⻔"
c = s.__iter__() # 获取迭代器
print(c.__next__()) # 使⽤迭代器进⾏迭代. 获取⼀个元素 我
print(c.__next__()) #
print(c.__next__()) #
print(c.__next__()) #
print(c.__next__()) #
print(c.__next__()) #
print(c.__next__()) #
print(c.__next__()) # StopIteration
# list是一个Iterable.可迭代的
lst = ["皇阿玛", "皇额娘", "容嬷嬷", "紫薇"]
# 获取迭代器
it = lst.__iter__()
# 迭代器往外拿元素. __next__()
print(it.__next__())    # 皇阿玛
print(it.__next__())    # 皇额娘
print(it.__next__())    # 容嬷嬷
print(it.__next__())    # 紫薇
# print(it.__next__())    # 迭代到最后一个元素之后. 再进行迭代就报错了
# 模拟for循环
lst = ["皇阿玛", "皇额娘", "容嬷嬷", "紫薇"]
# 模拟for循环
it = lst.__iter__()
while True:
    try:
        name = it.__next__()
        print(name)
    except StopIteration: # 拿完了
        break

 

posted @ 2018-07-17 22:24  shuai1993  阅读(111)  评论(0编辑  收藏  举报