day 10 - 1 函数进阶
函数进阶
命名空间和作用域
命名空间
命名空间 有三种
内置命名空间 —— python解释器
就是python解释器一启动就可以使用的名字存储在内置命名空间中
内置的名字在启动解释器的时候被加载进内存里
全局命名空间 —— 我们写的代码但不是函数中的代码
是在程序从上到下被执行的过程中依次加载进内存的
放置了我们设置的所有变量名和函数名
局部命名空间 —— 函数
就是函数内部定义的名字
当调用函数时 才会产生这个名称空间 随着函数执行的结束 这个命名空间随之消失
在局部:可以使用全局、内置命名空间中的名字
在全局:可以使用内置命名空间中的名字,但是不能用局部中使用
在内置:不能使用局部和全局的名字的
如下面的例子
- #局部命名空间的名字 不可以在全局空间中被调用
- def func():
- a = 1
- func()
- print(a) #报错——NameError: name 'a' is not defined
命名空间的使用原则:
1、在正常情况下,直接使用内置的名字
2、当我们在全局定义了和内置命名空间中同名的名字时,会使用全局的名字
3、在嵌套中,当自己的这一级中有所需的名字时,就不去找上一级找了
4、在嵌套中,如果自己没有 就找上一级要 上一级没有再找上一级 如果内置的名字空间也没有 就报错
5、多个函数应该拥有多个独立的局部名字空间,不互相共享
作用域
作用域 有两种
全局作用域 —— 作用在全局 —— 内置和全局命名空间中的名字都属于全局作用域 —— globals()
局部作用域 —— 作用在局部 —— 函数(局部命名空间中的名字属于局部作用域) —— locals()
我们接着来看下面 global 的例子
- #global 声明过得变量,让在函数外部的 print() 可以进行打印
- a = 1
- def func():
- global a #使用 global 进行声明
- a = 2
- func()
- print(a) #输出结果为 2
- b=1
- def func():
- #global b
- b = 2
- func()
- print(b) #此时结果还是 1,因为在内部的任何操作 不影响外部的
对于不可变数据类型 在局部可以查看全局作用域中的变量,但是不能直接修改
如果想要修改,需要在程序的一开始添加 global 声明
如果在一个局部(函数)内声明了一个 global 变量,那么这个变量在局部的所有操作将对全局的变量有效
接着我们对比着 global() 变量来看 locals() 变量
- #可以看出两个打印的内容一个为局部一个为全局
- a = 1
- b = 2
- def func():
- x = 'aaa'
- y = 'bbb'
- print(locals()) #输出局部的变量,根据 locals 所在的位置
- print(globals()) #永远打印全局的名字,可以看到打印出了好多内容
- func()
你一定会觉得 globals 函数在很多时候很好用(我也是这么觉得着)
可以 globals 这个函数涉及到代码的安全性 不推荐使用
可以通过传参和接收返回值 来完成原本使用 global 完成的事情
- #通过传参和接收返回值来时实现调用全局变量
- a = 1
- def func():
- global a
- a = 3
- func()
- print(a)
- #改为:
- a = 2
- def func(a):
- a += 1
- return a
- print(func(a)) #此时返回 3
函数的嵌套与调用
- #求两个数字的最大值
- def max(a,b):
- return a if a > b else b
- print(max(15,98))
- #求三个数的最大值
- def the_max(a,b,c):
- e = max(a,b) #把其中的两个值 丢给 max 去解决了
- return max(e,c)
- print(the_max(56,85,65))
不能直接调用函数内层的函数名
- def outer():
- def inner():
- print('inner')
- #outer() #没有结果
- #inner() #报错
- #outer(inner()) #报错
可以使用 nonlocal 实现函数嵌套调用
- # nonlocal
- # 对全局无效
- # 对局部 也只是对 最近的 一层 有影响
- def outer():
- a = 1
- def inner():
- b = 2
- print(a) #内部函数可以使用外部函数的变量
- print('inner')
- def inner2():
- print(a,b)
- print('inner2')
- nonlocal a #声明了上面第一次出现 a 局部变量,没找到 则报错(不常用)
- #global #在此处使用不能达到要求,因为此时 a = 1 为局部变量
- a += 1 #在这里操作是想修改上面 a = 1 的这个值(不可变数据类型的修改)
- inner2() #函数必须是先定义后调用
- print('局部变量 a:',a)
- inner()
- outer()
- #输出结果
- '''
- 1
- inner
- 1 2
- inner2
- 局部变量 a: 2 #这里可以看到外部函数的变量在内部函数中被修改了
- '''
函数的赋值
函数名可以用于:赋值、容器类型的元素、返回值、参数
- #函数名的赋值与作为容器类型的元素使用
- def func():
- print(123)
- #func() #函数名就是内存地址
- func2 = func #函数名可以用于赋值
- func2() #所以结果为 123
- l = [func,func2] #函数名可以作为容器类型的元素 如下面 for 循环
- print(l) #可以看出赋值后的内存地址是一致的
- for i in l:
- i()
- #函数名作为返回值与参数
- def func():
- print(123)
- def func2(f):
- f()
- return f #函数名可以作为函数的返回值
- func2(func) #函数名可以作为函数的参数
- func3 = func2(func) #用于接收返回值
- func3()
闭包
定义:
必须符合:是嵌套函数,且内部函数调用外部函数的变量
- def outer():
- a = 1
- def inner():
- print(a) #到这里就是一个闭包了
- print(inner.__closure__) #可以使用 __closure__ 来检测是否是闭包
- #返回 (<cell at : int object at ,) 这些就表示是一个闭包了
- inner()
- outer()
闭包常用形式:接收返回值
在一个函数的内部去使用它外部的变量
- #不过下面并不是闭包常用的形式
- def outer():
- a = 1
- def inner():
- print(a)
- inner()
- outer()
- #而下面的才是(采用接收返回值的形式)
- def outer():
- a = 1
- def inner():
- print(a)
- return inner
- inn = outer()
- inn()
- #在这里 a = 1 不会因为 outer() 函数的结束而消失,因为 inn() 后面可能会用到,所以才不会消失
- #使用闭包的好处在于 我保护了 a = 1 这个变量,它既不是全局变量,我又可以在使用它时,去使用它
- #延长了 a = 1 的声命周期 节省了创建和删除变量 a = 1 的时间
闭包的应用
- ##获取网站信息
- #现在已经可以拿到网页了,但是我们一般都要把它封装成一个函数
- from urllib.request import urlopen
- ret = urlopen('https://fanyi.baidu.com/translate#en/zh/inter').read()print(ret)
- print(ret)
- #我们使用闭包来封装它
- from urllib.request import urlopen
- def get_url():
- url = 'https://fanyi.baidu.com/translate#en/zh/inter'
- def inner():
- ret = urlopen(url).read()
- print(ret)
- return inner
- get_func = get_url()
- get_func()
- #这样的好处在于 就算在外部调用了 n 次 get_func() 而创建 n 次 url 这个变量
day 10 - 1 函数进阶的更多相关文章
- python学习笔记:第10天 函数进阶和作用域
目录 1. 函数进阶 2. 命名空间 3. 关键字global和nonlocal 1. 函数进阶 动态接收位置参数 之前写的函数都是固定参数的,假设有个函数需要的参数由几十个,一个个写在形参的位置会非 ...
- 巨蟒python全栈开发-第10天 函数进阶
一.今日主要内容总览(重点) 1.动态传参(重点) *,** *: 形参:聚合 位置参数*=>元组 关键字**=>字典 实参:打散 列表,字符串,元组=>* 字典=>** 形参 ...
- Python【day 10】函数进阶-小结
本节主要内容1.动态参数 *args **kwargs 形参:*args将多个位置参数聚合打包成元组 **kwargs将多个关键字参数聚合打包成字典 实参:*li1将列表进行解包打散成多个位置参数 * ...
- Python【day 10】函数进阶-动态函数
形参小结 1.位置参数2.默认值参数3.动态参数 1.*args 位置参数的动态传参. 系统会自动的把所有的位置参数聚合成元组 2.**kwargs 关键字参数的动态传参. 系统会自动的把所有的关键字 ...
- 10.Python初窥门径(函数进阶)
Python(函数进阶) 一.函数的传参(接上期) 形参角度(一共四种,后两种) 动态参数(万能参数)* # 定义一个函数时,*所有的位置参数聚合到一个元组中 def func(*args): # * ...
- python基础 (初识函数&函数进阶)
函数基础部分 .什么是函数? 函数是组织好的,可重复使用的,用来实现单一,或相关联功能的代码段. 函数能提高应用的模块性,和代码的重复利用率. 2.定义函数 定义:def 关键词开头,空格之后接函数名 ...
- python基础之 初识函数&函数进阶
函数基础部分 1.什么是函数? 函数是组织好的,可重复使用的,用来实现单一,或相关联功能的代码段.函数能提高应用的模块性,和代码的重复利用率. 2.定义函数 定义:def 关键词开头,空格之后接函数名 ...
- python函数进阶(函数参数、返回值、递归函数)
函数进阶 目标 函数参数和返回值的作用 函数的返回值 进阶 函数的参数 进阶 递归函数 01. 函数参数和返回值的作用 函数根据 有没有参数 以及 有没有返回值,可以 相互组合,一共有 4 种 组合形 ...
- python大法好——递归、内置函数、函数进阶
1.递归(自己干自己) def fun(n): n=n/2 print(n) if(n>2) fun(n) #函数调用 fun(10) 结果是5 2 1 0 递归的执行过程:递归执行到最里面一层 ...
随机推荐
- 在views中引用UserProfile报错RuntimeError: Model class apps.users.models.UserProfile doesn't declare an explicit app_label and isn't in an application in INSTALLED_APPS.
如图报错,在settings中,该加的也加了啊! 显然类似于网上最容易遇到的解决方案如下图,是没有任何意义的 只要在view中有 from .models import UserProfile,Ver ...
- Druid 配置及内置监控,Web页面查看监控内容 【我改】
转: Druid 配置及内置监控,Web页面查看监控内容 1.配置Druid的内置监控 首先在Maven项目的pom.xml中引入包 1 2 3 4 5 <dependency> ...
- 安装webpack-dev-server始终不成功
先安装了webpack,后来安装webpack-dev-server会一直出现这个问题,我把webpack提示的1.0.0 , 2.0.0 ,3.0.0全都在全局装了一遍都没用,还是会出现这个问题.最 ...
- hihocoder图像算子(高斯消元)
描述 在图像处理的技术中,经常会用到算子与图像进行卷积运算,从而达到平滑图像或是查找边界的效果. 假设原图为H × W的矩阵A,算子矩阵为D × D的矩阵Op,则处理后的矩阵B大小为(H-D+1) × ...
- JavaEE正常开发怎么做
如果不使用第三方框架,用JavaEE的内容怎么去开发呢? 例如这里有一个需求: 最传统的方案如下:
- java io系列23之 BufferedReader(字符缓冲输入流)
转载请注明出处:http://www.cnblogs.com/skywang12345/p/io_23.html 更多内容请参考:java io系列01之 "目录" Buffere ...
- 9.组合模式(Composite Pattern)
动机(Motivate): 组合模式有时候又叫做部分-整体模式,它使我们树型结构的问题中,模糊了简单元素和复杂元素的概念,客户程序可以向处理简单元素一样来处理复杂元素,从而使得客户程序与复杂元素 ...
- centos 6.5 安装jdk1.8
1.源码包准备: 首先到官网下载jdk-8u66-linux-x64.tar.gz, http://www.oracle.com/technetwork/java/javase/downloads/j ...
- 【英文文档】Solidifier for Windows Installation Guide
Page 1Solidifier for Windows Installation Guide Page 2McAfee, Inc.McAfee® Solidifier for Windows In ...
- Shell编程(三)Shell特性
!$:显示上一条命令最后一个参数 $?: 上个命令的退出状态,或函数的返回值. alias xxx="命令":给命令取别名 xxx 通过 vim ~/.bashrc 里编辑,可以来 ...