一、【函数名】

1)函数名本质上它也是一种变量,特殊的变量;
(碰到同名其它变量,依照从上往下的代码执行赋值。)
单独打印函数名,输出的是它对应的内存地址: 例:
def funcl():
print(666)
print(funcl) 返回如下:
<function funcl at 0x0000000000DF5488> 2)函数名可以赋值给其它变量名;
def funcl():
print(666) f1 = funcl
f1() 666 3)函数名可以作为容器类的元素;
def funcl():
print(666)
# print(funcl) f1 = funcl
f1() def f2():
print(222) def f3():
print(333) def f4():
print(444) li =[f1, f2, f3, f4]
print(li) # 返回的是对应的内存地址 for i in li:
i() # 依次执行函数,可以看到函数名作为列表(容器)的元素也是可以的。
666
222
333
444 4)函数名可以作为参数;
def f1():
print(666) def f2(a):
a()
print(777) f2(f1) 输出的结果:
666
777 上例中f1函数名是作为f2函数的参数。 5)函数名可以作为函数的返回值。
例:
def f1():
print(666) def f2():
return f1 f2()() # 输出666 def f3():
def f4():
print(777)
return f4 f3()() #输出 777

以上例子可以看出函数名也可以作为函数的返回值,而且通过return返回的嵌套函数可以调用执行成功。

像上例中的f3()()如果改成f4()是会报错:NameError: name 'f4' is not defined,原因就是全局命名空间中找不到f4()函数定义。所以这是命名空间很神奇的一个地方。

二、【闭包函数】

内层函数对外层函数,非全局变量的引用。

判断闭包函数:函数名.closure(),返回的值中有cell这个元素表示该函数为闭包函数。

闭包函数的机制:当函数开始执行时,如果遇到了闭包,在内存当中会为闭包开辟一个内存空间,用于将闭包中的变量等值放入其中,并不会随着函数的执行完毕而消失。

函数内部定义的函数称为内部函数

主要作用有:

1)缓存,节省内存空间;例如爬虫用,(不断重复爬取同一网页的情况下)

2)装饰器,最能完整体现出闭包的作用。

由于作用域的关系,

我们不能直接拿到函数内部的变量和函数了。如果我们就是想拿怎么办呢?通过返回值!

函数内的变量要想在函数外部用,可以直接返回这个变量,那么如果想在函数外部调用函数内部的函数呢?

是不是直接就把这个函数的名字返回就好了?

这才是闭包函数最常用的用法。所以这也是装饰器之所以是闭包函数最能完整体现用法的原因。

例:闭包函数的运用,引用外层的函数。
def func():
name = 'eva'
def inner():
print(name)
return inner func() # 直接执行func,并没有调用到func里面的inner函数,不会输出eva
f = func()
f() # 相当于是执行func()(),而func()中返回了inner函数,
# 所以又相当于是在func函数体内部中执行func(inner),所以就能正常执行了。 #输出 eva 例:判断是否为闭包函数
函数名.__closure__()
#输出的__closure__有cell元素 :是闭包函数
def func():
name = 'eva'
def inner():
print(name)
print(inner.__closure__)
return inner f = func()
f() print('我是华丽的分割线'.center(30, '-')) #输出的__closure__为None :不是闭包函数(没有引用外层,试图引用的是全局的变量,所以不为闭包)
name = 'egon'
def func2():
def inner():
print(name)
print(inner.__closure__)
return inner f2 = func2()
f2() (<cell at 0x0000000000BF9138: str object at 0x0000000000BE0D18>,)
eva
-----------我是华丽的分割线-----------
None
egon 例:闭包的嵌套(两层,还可以嵌套到三层,一般三层己够满足需要了)
下面是借助不断给函数名赋值成变量来调用嵌套的函数的,这个方法其实在说到装饰器时会用上,为什么要简化成一个变量名()的方式,就是为了装饰其他函数用(不用改变其他函数的表现形式)
def wrapper():
money = 1000
def func():
name = 'eva'
def inner():
print(name, money)
return inner
return func f = wrapper()
i = f()
i() eva 1000 例:闭包函数获取网络应用(简单爬虫雏形)
下例为我爬取我的个人wordpress博客首页所用的简单代码,
到最后的内容需要用到decode解码才能看到页面源代码。
还可以更进一步使用文件操作写入到文件。
from urllib.request import urlopen def index():
url = "https://www.tielemao.com"
def get():
return urlopen(url).read()
return get tielemao = index()
content = tielemao()
print(content.decode('utf-8')) 写到文件上保存:
from urllib.request import urlopen def index():
url = "https://www.tielemao.com"
def get():
return urlopen(url).read()
return get tielemao = index()
content = tielemao()
# print(content.decode('utf-8'))
s = content.decode('utf-8')
with open('tielemao_index.html', encoding='utf-8', mode='a') as f1:
f1.write(s)

end

2018-4-3

铁乐学Python_day11_闭包函数的更多相关文章

  1. 铁乐学python_Day44_IO多路复用

    目录 IO模型介绍 阻塞IO(blocking IO) 非阻塞IO(non-blocking IO) 多路复用IO(IO multiplexing) 异步IO(Asynchronous I/O) IO ...

  2. 铁乐学python_Day43_协程

    铁乐学python_Day43_协程 引子 之前我们学习了线程.进程的概念,了解了在操作系统中进程是资源分配的最小单位,线程是CPU调度的最小单位. 按道理来说我们已经算是把cpu的利用率提高很多了. ...

  3. 铁乐学python_Day42_线程池

    铁乐学python_Day42_线程池 concurrent.futures 异步调用模块 concurrent.futures模块提供了高度封装的异步调用接口 ThreadPoolExecutor: ...

  4. 铁乐学python_Day42_锁和队列

    铁乐学python_Day42_锁和队列 例:多个线程抢占资源的情况 from threading import Thread import time def work(): global n tem ...

  5. 铁乐学python_Day39_多进程和multiprocess模块2

    铁乐学python_Day39_多进程和multiprocess模块2 锁 -- multiprocess.Lock (进程同步) 之前我们千方百计实现了程序的异步,让多个任务可以同时在几个进程中并发 ...

  6. 铁乐学python_Day38_多进程和multiprocess模块1

    铁乐学python_Day38_多进程和multiprocess模块1 [进程] 运行中的程序就是一个进程. 所有的进程都是通过它的父进程来创建的. 因此,运行起来的python程序也是一个进程,那么 ...

  7. 铁乐学Python_Day34_Socket模块2和黏包现象

    铁乐学Python_Day34_Socket模块2和黏包现象 套接字 套接字是计算机网络数据结构,它体现了C/S结构中"通信端点"的概念. 在任何类型的通信开始之前,网络应用程序必 ...

  8. 铁乐学python_day25_序列化模块

    铁乐学python_day25_序列化模块 部份内容摘自博客http://www.cnblogs.com/Eva-J/ 回顾内置方法: __len__ len(obj)的结果依赖于obj.__len_ ...

  9. 铁乐学python_day24_面向对象进阶1_内置方法

    铁乐学python_day24_面向对象进阶1_内置方法 题外话1: 学习方法[wwwh] what where why how 是什么,用在哪里,为什么,怎么用 学习到一个新知识点的时候,多问问上面 ...

随机推荐

  1. 简单canvas刮刮乐

    好久没玩canvas了,随便写点效果玩玩.要开始重新拾起这门牛x的技术了,工作中不一定能用得上,以后说不定就能发挥用处了. <!DOCTYPE html> <html lang=&q ...

  2. 记录自己使用到的git命令行代码与git使用流程

    1.安装创建版本库 新建一个文件夹,用命令行实现: $ cd /d             //进入d盘 $ mkdir gitproject      //新建gitproject文件夹 $ cd ...

  3. H5如何用Canvas画布生成并保存带图片文字的新年快乐的海报

    摘要:初略算了算大概有20天没有写博客了,原本是打算1月1号元旦那天写一个年终总结的,博客园里大佬们都在总结过去,迎接将来,看得我热血沸腾,想想自己也工作快2年了,去年都没有去总结一下,今年势必要总结 ...

  4. JavaScript文档对象模型

    文档对象模型(Document Object Model, DOM)是W3C提出的用于访问和修改文档的接口. JavaScript设计的初衷是为Web提供交互功能,它通过DOM接口来访问和修改文档. ...

  5. python单链表

    #!/usr/bin/env python3 # -*- coding:utf-8 -*- class LNode: """ 结点类 """ ...

  6. Ionic CLI 升级到最新版本

    由于Ionic 自身也在不停的更新当中, 所以开发者经常会遇到从官方的CLI 命令,在命令行窗口中执行出错的情况. 就比如我一个月之前安装的ionic 2.2.2版本,已不能使用最新的3.2.0 CL ...

  7. SQL Server - 文件组,文件,备份,分区

    FileGroup:文件组,为逻辑划分:Files:文件,为实际文件,需要指定文件属于哪个文件组. 使用多个文件的有点:可以将磁盘I/O压力分散,提供按文件和文件组(按文件和文件组进行备份需要设置数据 ...

  8. C# 的逻辑运算

    &.^.!和|操作符称为逻辑操作符,用逻辑操作符把运算对象连接起来符合C#语法的式子称为逻辑表达式.逻辑 操作符“!”和“^”只作用于其后的操作数,故称为一元操作符.而“&&” ...

  9. C# 实现寻峰算法的简单优化(包含边峰,最小峰值,峰距)

      核心寻峰算法的原理参考Ronny,链接:投影曲线的波峰查找, C#翻译原理代码参考sowhat4999,链接:C#翻译Matlab中findpeaks方法 前人种树,后人乘凉.感谢原作者详细的解释 ...

  10. 2017年5月22日 HTML基础知识(一)

    一.Html 结构 1.1.HTML基本文档格式—<html> 标记 —<html>文档的头部好和主体内容 </html>  根标记 —<head> 文 ...