13 Python 函数进阶
代码在运行伊始,创建的存储“变量名与值的关系”的空间叫做全局命名空间,在函数的运行中开辟的临时的空间叫做局部命名空间
命名空间和作用域
命名空间的本质:存放名字与值的绑定关系
>>> 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 函数进阶的更多相关文章
- python函数进阶(函数参数、返回值、递归函数)
函数进阶 目标 函数参数和返回值的作用 函数的返回值 进阶 函数的参数 进阶 递归函数 01. 函数参数和返回值的作用 函数根据 有没有参数 以及 有没有返回值,可以 相互组合,一共有 4 种 组合形 ...
- 第六篇:Python函数进阶篇
在了解完了 Python函数基础篇之后,本篇的存在其实是为了整合知识,由于该篇的知识是否杂乱,故大家可以通过点开点连接直接进入其详细介绍,该篇主要大致的介绍一下几个知识点: 一.Python的迭代器 ...
- python 函数进阶与闭包
函数的命名空间和作用域 引言 现在有个问题,函数里面的变量,在函数外面能直接引用么? def func1(): m = 1 print(m) print(m) #这行报的错 报错了: NameErro ...
- python函数进阶
知识内容: 1.函数即变量 2.嵌套函数 3.lambda表达式与匿名函数 4.递归函数 5.函数式编程简介 6.高阶函数与闭包 一.函数即变量 1.变量的本质 声明一个变量,在python里本质上讲 ...
- python -- 函数进阶
一.函数参数-动态传参 1.形参: * 在形参位置, 表示此参数为不定参数,接受的是位置参数 并且接收到的位置参数的动态传参都是元组 def fu ...
- 万恶之源 - Python函数进阶
函数参数-动态参数 之前我们说过传参,如果我们在传参数的时候不很清楚有哪些的时候,或者说给一个函数传了很多参数,我们就要写很多,很麻烦怎么办呢,我们可以考虑使用动态参数 形参的第三种:动态参数 动态参 ...
- Python 函数进阶(filter/map/json/zip)
一.函数即变量 def say(name): print(name)ybq = say #可以被赋值给其他变量ybq('Amily') #调用函数 函数名:say 函数体:第1-2行 返回值:retu ...
- Python—函数进阶篇
lambda表达式(匿名函数表达式) 作用:创建一个匿名函数对象.同def类似,但不提供函数名. 语法:lambda [形参1,形参2,...] : 表达式 语法说明 lambda 只是一个表达式,它 ...
- Python函数进阶:闭包、装饰器、生成器、协程
返回目录 本篇索引 (1)闭包 (2)装饰器 (3)生成器 (4)协程 (1)闭包 闭包(closure)是很多现代编程语言都有的特点,像C++.Java.JavaScript等都实现或部分实现了闭包 ...
随机推荐
- 从零开始学android -- Service
废话不多说了,Service是四大组件之一,是一个后台处理长时间运行在主线程不需要依赖ui界面显示的应用组件,切记不能在service中做耗时操作,会阻塞主线程,要做也要在service中开个子线程做 ...
- LeakCanary Android 和 Java 内存泄露检测
说起内存泄漏还是挺让人头疼的,而且不是每个手机都会发生的情况,往往又不易察觉,那么今天我们就来介绍下LeakCanary这个工具 githup:https://github.com/square/le ...
- java Collection-Map 之 TreeMap
TreeMap 内部定义了一个类 static final class Entry<K,V> implements Map.Entry<K,V>,(自平衡红黑二叉树)作为数据 ...
- python pymysql安装
==================pymysql=================== 由于 MySQLdb 模块还不支持 Python3.x,所以 Python3.x 如果想连接MySQL需要安装 ...
- Obj-C数组以及字符串拼接与分割
本文转载至 http://mobile.51cto.com/iphone-392148.htm Obj-C只是增加了一点“特殊语料”的C语言,所以可以用printf()代替NSLog().但我们建议使 ...
- html5中form表单新增属性以及改良的input标签元素的种类
在HTML5中,表单新增了一些属性,input标签也有了更多的type类型,有些实现了js才能实现的特效,但目前有些浏览器不能全部支持.下面是一些h5在表单和input标签上的一些改动. <!D ...
- javascript修改图片链接地址
<!DOCTYPE html><html xmlns="http://www.w3.org/1999/xhtml"><head> < ...
- mysql中的乐观锁和悲观锁
mysql中的乐观锁和悲观锁的简介以及如何简单运用. 关于mysql中的乐观锁和悲观锁面试的时候被问到的概率还是比较大的. mysql的悲观锁: 其实理解起来非常简单,当数据被外界修改持保守态度,包括 ...
- flex (html弹性布局)
flex是什么? 任何容器都可以指定为flex布局: .box{ display: flex; /* 行内元素可以使用:inline-flex,webket内核浏览器必须 -webkit-flex ...
- mysql(root用户密码设置)
root密码重置 修改root用户的密码: /*登录mysql*/ mysql -uroot -p123 /*切换数据库*/ use mysql /*修改root用户的密码*/ update user ...