python全栈开发- 前??能-迭代器

2018-07-18 01:15:50来源:博客园 阅读 ()

新老客户大回馈,云服务器低至5折

python_day_12

今日主要内容
1, 函数名的应用,第一类对象
函数名可以像变量一样进行使用
1.赋值
2.作为list元素
3.作为参数
4.作为返回值

2, 闭包
内部函数访问外部函数的局部变量.
好处:

  • 1.安全
  • 2.常驻内存. 提高效率
  • 3, 迭代器

可迭代对象(Iterable):内部包含__iter__().
迭代器(Iterator): 内部含有__iter__() __next__()
str, list, tuple, set, dict
f, range

迭代器的特点:

  • 1.省内存
  • 2.惰性机制
  • 3.只能向前.

11. 前方高能-迭代器 本节主要内容:

  • 1. 函数名的使?以及第?类对象
  • 2. 闭包
  • 3. 迭代器

?. 函数名的运?.

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

1. 函数名的内存地址

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

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

def func():
   print("呵呵")
print(func)
a = func # 把函数当成?个变量赋值给另?个变量
a() # 函数调? func()

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

def func1():
   print("呵呵")
def func2():
   print("呵呵")
def func3():
   print("呵呵")
def func4():
   print("呵呵")
lst = [func1, func2, func3]
for i in lst:
   i()

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

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

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() # 执?上?返回的函数    

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

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()()()    

由它我们可以引出闭包的好处. 由于我们在外界可以访问内部函数. 那这个时候内部函 数访问的时间和时机就不?定了, 因为在外部, 我可以选择在任意的时间去访问内部函数. 这 个时候. 想?想. 我们之前说过, 如果?个函数执?完毕. 则这个函数中的变量以及局部命名 空间中的内容都将会被销毁. 在闭包中. 如果变量被销毁了. 那内部函数将不能正常执?. 所 以. python规定. 如果你在内部函数中访问了外层函数中的变量. 那么这个变量将不会消亡. 将会常驻在内存中. 也就是说. 使?闭包, 可以保证外层函数中的变量在内存中常驻. 这样做 有什么好处呢? 非常?的好处. 我们来看?个关于爬?的代码:

from urllib.request import urlopen
def but():
     content = urlopen("http://www.xiaohua100.cn/index.html").read()
     def get_content():
         return content
     return get_content
fn = but() # 这个时候就开始加载校花100的内容
# 后?需要?到这??的内容就不需要在执??常耗时的?络连接操作了
content = fn() # 获取内容
print(content)
content2 = fn() # 重新获取内容
print(content2)

综上, 闭包的作?就是让?个变量能够常驻内存. 供后?的程序使?.

三. 迭代器 我们之前?直在?可迭代对象进?迭代操作. 那么到底什么是可迭代对象. 本?节主要讨 论可迭代对象. ?先我们先回顾?下?前我们所熟知的可迭代对象有哪些: str, list, tuple, dict, set.

我们发现这?个可以进?for循环的东?都有__iter__函数, 包括range也有. 可以??试? 下. 这是查看?个对象是否是可迭代对象的第?种办法. 我们还可以通过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

综上. 我们可以确定. 如果对象中有__iter__函数. 那么我们认为这个对象遵守了可迭代协议. 就可以获取到相应的迭代器. 这?的__iter__是帮助我们获取到对象的迭代器. 我们使?迭代 器中的__next__()来获取到?个迭代器中的元素. 那么我们之前讲的for的?作原理到底是什 么? 继续看代码

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

for循环的机制:

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

总结:

Iterable: 可迭代对象. 内部包含__iter__()函数

Iterator: 迭代器. 内部包含__iter__() 同时包含__next__().

迭代器的特点:

  • 1. 节省内存.
  • 2. 惰性机制
  • 3. 不能反复, 只能向下执?.

 

我们可以把要迭代的内容当成?弹. 然后呢. 获取到迭代器__iter__(), 就把?弹都装在弹夹 中. 然后发射就是__next__()把每?个?弹(元素)打出来. 也就是说, for循环的时候. ?开始的 时候是__iter__()来获取迭代器. 后?每次获取元素都是通过__next__()来完成的. 当程序遇到 StopIteration将结束循环.


2018-07-17  19:11:38

 

标签:

版权申明:本站文章部分自网络,如有侵权,请联系:west999com@outlook.com
特别注意:本站所有转载文章言论不代表本站观点,本站所提供的摄影照片,插画,设计作品,如需使用,请与原作者联系,版权归原作者所有

上一篇:学会Python之后!亲朋好友都夸我厉害!用Python买到最优惠的家具

下一篇:《11招玩转网络安全》之第四招:low级别的DVWA SQL注入