代码在运行伊始,创建的存储“变量名与值的关系”的空间叫做全局命名空间,在函数的运行中开辟的临时的空间叫做局部命名空间

命名空间和作用域

  命名空间的本质:存放名字与值的绑定关系

 >>> import this
The Zen of Python, by Tim Peters Beautiful is better than ugly.
Explicit is better than implicit.
Simple is better than complex.
Complex is better than complicated.
Flat is better than nested.
Sparse is better than dense.
Readability counts.
Special cases aren't special enough to break the rules.
Although practicality beats purity.
Errors should never pass silently.
Unless explicitly silenced.
In the face of ambiguity, refuse the temptation to guess.
There should be one-- and preferably only one --obvious way to do it.
Although that way may not be obvious at first unless you're Dutch.
Now is better than never.
Although never is often better than *right* now.
If the implementation is hard to explain, it's a bad idea.
If the implementation is easy to explain, it may be a good idea.
Namespaces are one honking great idea -- let's do more of those!

在python之禅中提到过:命名空间是一种绝妙的理念,让我们尽情的使用发挥吧!

命名空间一共分为三种:

  全局命名空间

  局部命名空间

  内置命名空间

*内置命名空间中存放了python解释器为我们提供的名字:input,print,str,list,tuple...它们都是我们熟悉的,拿过来就可以用的方法。

三种命名空间之间的加载与取值顺序:

加载顺序:内置命名空间(程序运行前加载)->全局命名空间(程序运行中:从上到下加载)->局部命名空间(程序运行中:调用时才加载)

取值:

  在局部调用:局部命名空间->全局命名空间->内置命名空间

  在局部使用变量取值情况

 x = 1
def f(x):
print(x) print(10)

  在全局调用:全局命名空间->内置命名空间

  在全局引用变量x

 x = 1
def f(x):
print(x) f(10)
print(x)

在全局引用内置max 

 print(max)

作用域

  作用域就是作用范围,按照生效范围可以分为全局作用域和局部作用域。

  全局作用域:包含内置名称空间、全局名称空间,在整个文件的任意位置都能被引用、全局有效

  局部作用域:局部名称空间,只能在局部范围生效

  globals和locals方法

  在全局引用globals和locals

 print(globals())
print(locals()) C:\Users\panhw\AppData\Local\Programs\Python\Python36\python.exe C:/Users/panhw/Desktop/学习文档/python/day15.py
{'__name__': '__main__', '__doc__': None, '__package__': None, '__loader__': <_frozen_importlib_external.SourceFileLoader object at 0x0000023BB77CA4A8>, '__spec__': None, '__annotations__': {}, '__builtins__': <module 'builtins' (built-in)>, '__file__': 'C:/Users/panhw/Desktop/学习文档/python/day15.py', '__cached__': None, 'sys': <module 'sys' (built-in)>, 'li': [2, 3, 5, 10, 15, 16, 18, 22, 26, 30, 32, 35, 41, 42, 43, 55, 56, 66, 67, 69, 72, 76, 82, 83, 88], 'count': 1}
{'__name__': '__main__', '__doc__': None, '__package__': None, '__loader__': <_frozen_importlib_external.SourceFileLoader object at 0x0000023BB77CA4A8>, '__spec__': None, '__annotations__': {}, '__builtins__': <module 'builtins' (built-in)>, '__file__': 'C:/Users/panhw/Desktop/学习文档/python/day15.py', '__cached__': None, 'sys': <module 'sys' (built-in)>, 'li': [2, 3, 5, 10, 15, 16, 18, 22, 26, 30, 32, 35, 41, 42, 43, 55, 56, 66, 67, 69, 72, 76, 82, 83, 88], 'count': 1}

  在局部引用globals和locals

 def func():
a = 12
b = 20
print(locals())
print(globals()) func() C:\Users\panhw\AppData\Local\Programs\Python\Python36\python.exe C:/Users/panhw/Desktop/学习文档/python/day15.py
{'b': 20, 'a': 12}
{'__name__': '__main__', '__doc__': None, '__package__': None, '__loader__': <_frozen_importlib_external.SourceFileLoader object at 0x000001FEE5D2A4A8>, '__spec__': None, '__annotations__': {}, '__builtins__': <module 'builtins' (built-in)>, '__file__': 'C:/Users/panhw/Desktop/学习文档/python/day15.py', '__cached__': None, 'sys': <module 'sys' (built-in)>, 'li': [2, 3, 5, 10, 15, 16, 18, 22, 26, 30, 32, 35, 41, 42, 43, 55, 56, 66, 67, 69, 72, 76, 82, 83, 88], 'count': 1, 'func': <function func at 0x000001FEE4123E18>}

  global 关键字

 a = 10
def func():
global a
a = 20 print(a)
func()
print(a)

函数的嵌套和作用域链

  函数的嵌套调用

 def max2(x,y):
m = x if x>y else y
return m def max4(a,b,c,d):
res1 = max2(a,b)
res2 = max2(res1,c)
res3 = max2(res2,d)
return res3 # max4(23,-7,31,11)

  函数的嵌套定义

 def f1():
print("in f1")
def f2():
print("in f2") f2()
f1()

嵌套定义(一)

嵌套定义(二)

  函数的作用域链

 def f1():
a = 1
def f2():
print(a)
f2() f1()

作用域链(一)

 def f1():
a = 1
def f2():
def f3():
print(a)
f3()
f2() f1()

作用域链(二)

 def f1():
a = 1
def f2():
a = 2
f2()
print('a in f1 : ',a) f1()

作用域链(三)

  nonlcoal 关键字

    1.外部必须有这个变量
    2.在内部函数声明nonlocal变量之前不能再出现同名变量
    3.内部修改这个变量如果想在外部有这个变量的第一层函数中生效

 def f1():
a = 1
def f2():
nonlocal a
a = 2
f2()
print('a in f1 : ',a) f1()

函数名的本质

  函数名本质上就是函数的内存地址

  1.可以被引用

 def func():
print('in func') f = func
print(f)

函数引用

  2.可以被当作容器类型的元素

 def f1():
print('f1') def f2():
print('f2') def f3():
print('f3') l = [f1,f2,f3]
d = {'f1':f1,'f2':f2,'f3':f3}
#调用
l[0]()
d['f2']()

当做容器

  3.可以当作函数的参数和返回值

 第一类对象(first-class object)指
1.可在运行期创建
2.可用作函数参数或返回值
3.可存入变量的实体。

闭包

  闭包函数:

    内部函数包含对外部作用域而非全剧作用域名字的引用,该内部函数称为闭包函数
    函数内部定义的函数称为内部函数

  在计算机科学中,闭包(Closure)是词法闭包(Lexical Closure)的简称,是引用了自由变量的函数。这个被引用的自由变量将和这个函数一同存在,即使已经离开了创造它的环境也不例外。所以,有另一种说法认为闭包是由函数和与其相关的引用环境组合而成的实体。闭包在运行时可以有多个实例,不同的引用环境和相同的函数组合可以产生不同的实例。

 def func(name):
def inner_func(age):
print 'name:', name, 'age:', age
return inner_func bb = func('the5fire')
bb(26) # >>> name: the5fire age: 26

  闭包函数最常用的用法

 def func():
name = 'eva'
def inner():
print(name)
return inner f = func()
f()

  判断闭包函数的方法__closure__

 #输出的__closure__有cell元素 :是闭包函数
def func():
name = 'eva'
def inner():
print(name)
print(inner.__closure__)
return inner f = func()
f() #输出的__closure__为None :不是闭包函数
name = 'egon'
def func2():
def inner():
print(name)
print(inner.__closure__)
return inner f2 = func2()
f2()

  闭包嵌套

 def wrapper():
money = 1000
def func():
name = 'eva'
def inner():
print(name,money)
return inner
return func f = wrapper()
i = f()
i()

  闭包函数获取网络应用

 from urllib.request import urlopen

 def index():
url = "http://www.xiaohua100.cn/index.html"
def get():
return urlopen(url).read()
return get xiaohua = index()
content = xiaohua()
print(content)

命名空间:

  一共有三种命名空间从大范围到小范围的顺序:内置命名空间、全局命名空间、局部命名空间

作用域(包括函数的作用域链):

小范围的可以用大范围的
但是大范围的不能用小范围的
范围从大到小(图)

在小范围内,如果要用一个变量,是当前这个小范围有的,就用自己的
如果在小范围内没有,就用上一级的,上一级没有就用上上一级的,以此类推。
如果都没有,报错

函数的嵌套:

  嵌套调用

  嵌套定义:定义在内部的函数无法直接在全局被调用

函数名的本质:

  就是一个变量,保存了函数所在的内存地址

闭包:

  内部函数包含对外部作用域而非全剧作用域名字的引用,该内部函数称为闭包函数

2. 为什么使用闭包

基于上面的介绍,不知道读者有没有感觉这个东西和类有点相似,相似点在于他们都提供了对数据的封装。不同的是闭包本身就是个方法。和类一样,我们在编程时经常会把通用的东西抽象成类,(当然,还有对现实世界——业务的建模),以复用通用的功能。闭包也是一样,当我们需要函数粒度的抽象时,闭包就是一个很好的选择。

在这点上闭包可以被理解为一个只读的对象,你可以给他传递一个属性,但它只能提供给你一个执行的接口。因此在程序中我们经常需要这样的一个函数对象——闭包,来帮我们完成一个通用的功能,比如后面会提到的——装饰器。

3. 使用闭包

第一种场景 ,在python中很重要也很常见的一个使用场景就是装饰器,Python为装饰器提供了一个很友好的“语法糖”——@,让我们可以很方便的使用装饰器,装饰的原理不做过多阐述,简言之你在一个函数func上加上@decorator_func, 就相当于decorator_func(func):

 def decorator_func(func):
def wrapper(*args, **kwargs):
return func(*args, **kwargs)
return wrapper @decorator_func
def func(name):
print 'my name is', name # 等价于
decorator_func(func)

13 Python 函数进阶的更多相关文章

  1. python函数进阶(函数参数、返回值、递归函数)

    函数进阶 目标 函数参数和返回值的作用 函数的返回值 进阶 函数的参数 进阶 递归函数 01. 函数参数和返回值的作用 函数根据 有没有参数 以及 有没有返回值,可以 相互组合,一共有 4 种 组合形 ...

  2. 第六篇:Python函数进阶篇

    在了解完了 Python函数基础篇之后,本篇的存在其实是为了整合知识,由于该篇的知识是否杂乱,故大家可以通过点开点连接直接进入其详细介绍,该篇主要大致的介绍一下几个知识点:  一.Python的迭代器 ...

  3. python 函数进阶与闭包

    函数的命名空间和作用域 引言 现在有个问题,函数里面的变量,在函数外面能直接引用么? def func1(): m = 1 print(m) print(m) #这行报的错 报错了: NameErro ...

  4. python函数进阶

    知识内容: 1.函数即变量 2.嵌套函数 3.lambda表达式与匿名函数 4.递归函数 5.函数式编程简介 6.高阶函数与闭包 一.函数即变量 1.变量的本质 声明一个变量,在python里本质上讲 ...

  5. python -- 函数进阶

    一.函数参数-动态传参       1.形参:         *   在形参位置, 表示此参数为不定参数,接受的是位置参数            并且接收到的位置参数的动态传参都是元组 def fu ...

  6. 万恶之源 - Python函数进阶

    函数参数-动态参数 之前我们说过传参,如果我们在传参数的时候不很清楚有哪些的时候,或者说给一个函数传了很多参数,我们就要写很多,很麻烦怎么办呢,我们可以考虑使用动态参数 形参的第三种:动态参数 动态参 ...

  7. Python 函数进阶(filter/map/json/zip)

    一.函数即变量 def say(name): print(name)ybq = say #可以被赋值给其他变量ybq('Amily') #调用函数 函数名:say 函数体:第1-2行 返回值:retu ...

  8. Python—函数进阶篇

    lambda表达式(匿名函数表达式) 作用:创建一个匿名函数对象.同def类似,但不提供函数名. 语法:lambda [形参1,形参2,...] : 表达式 语法说明 lambda 只是一个表达式,它 ...

  9. Python函数进阶:闭包、装饰器、生成器、协程

    返回目录 本篇索引 (1)闭包 (2)装饰器 (3)生成器 (4)协程 (1)闭包 闭包(closure)是很多现代编程语言都有的特点,像C++.Java.JavaScript等都实现或部分实现了闭包 ...

随机推荐

  1. Web性能测试工具:http_load安装&使用简介

    除了siege,在Web性能测试工具中,http_load也是比较热门和常见的一款,有时因为种种原因,只能使用现成的工具,所以多了解和掌握一种Web性能测试工具是很有必要的. 1.下载安装包 略过 2 ...

  2. X264学习1:简介

    H.264是视频编码标准. X264是它的开源实现,是视频编码器. 目录 [隐藏]  1 编码器特性 2 输入输出文件类型 2.1 输入 2.2 输出 3 preset和tune系统 3.1 --pr ...

  3. 12 Memcached 缓存无底洞现象

    一:Memcached 缓存无底洞现象(1)facebook的工作人员反应的,facebook在2010年左右,memcached节点就已经达到了3000个,存储的数据进千G的数据存储. 他们发现一个 ...

  4. java程序优化

    程序代码优化要点: 字符串优化:分析String源码,了解String常用方法,使用StringBuffer.StringBuilder. List.Map.Set优化:分析常用ArrayList.L ...

  5. 时下世界上最先进的液晶面板技术---ips

    IPS是英文In-Plane Switching的缩写,英文含义为平面转换屏幕技术,由日立公司于2001推出的液晶面板技术,俗称“Super TFT”,是目前世界上最先进的液晶面板技术,目前已经广泛使 ...

  6. 安装PyTorch 0.4.0

    https://blog.csdn.net/sunqiande88/article/details/80085569 https://blog.csdn.net/xiangxianghehe/arti ...

  7. PHP 和 AJAX MySQL 数据库实例

    HTML 表单 <!DOCTYPE html> <html lang="en"> <head> <meta charset="U ...

  8. EasyNVR无插件直播服务器软件如何自己更改web界面(网页的自定修改)

    背景需求 很多用户都在使用了EasyNVR,看到EasyNVR自身带有的界面后有这样的需求,就是需要更改一下web前端的一些样式,当前EasyhNVR为3.0版本,web前端为了增加前端的运行效率和减 ...

  9. EasyNVR无插件直播服务器播放页面的集成----单独的播放器样式

    背景需求: EasyNVR自身拥有独立的客户端体系,安卓和IOS拥有各自独立的APP, 安卓下载地址:https://fir.im/EasyNVR: IOS下载可直接在APPstore搜索EasyNV ...

  10. 在jsp中嵌入javascript代码执行对html的影响方式

    1 javascript的作用范围 javascript操作的是html dom树. 它可以用来直接写入html标签:修改html的内容:响应事件:修改html中的图像:修改html的样式等等. 2 ...