函数 (二) 名称空间与作用域

一、什么是名称空间

我们写一段代码,里面肯定会定义一些变量名,函数名,而一旦我们运行代码,python解释器在加载这些代码的时候,会在内存中开辟一片空间专门用来存放这些名字以及这些名字所绑定的值的关系,

这块内存就被称为名称空间。

二、名称空间分类

名称空间分为三种:

△内置名称空间

  内置名称空间是用来存放python解释器的一些内置方法明以及变量名的。这些名称是在解释器启动的时候就加载好的,我们随时可以调用。比如常见的 print( )、input( )、len( )等都是内置方法,我们在写代码的时候直接调用就行。而存放他们的名字的地方就叫做内置名称空间。

△全局名称空间

  我们在写一段代码的时候,除了函数内所定义的变量以及函数外,其他的变量名以及函数名所存放的地方就叫做全局名称空间。一旦我们定义好这个变量或者函数,那么我们可以在代码的任意地方调用。

△局部名称空间

  存放函数内定义的变量名以及函数内嵌套的函数名的地方叫做局部名称空间。他们只能在函数内部(包括函数内嵌套的函数内部)被调用。

三、名称的加载顺序

当我们打开解释器的时候内置变量以及函数就立即被加载,当我们执行一段代码的时候,全局变量以及函数才被加载,但是函数内部并不会被执行,只有在函数被调用的时候才会加载它内部的变量以及内嵌函数,所以,名称的加载顺序是:内置名称---->全局名称---->局部名称

四、名字的查找顺序

与名称的加载顺序刚好相反,python解释器在用到一个变量或者函数的时候,它会优先从局部名称空间去查找,如果没有,再到全部名称空间去查找,如果还没有,才会去内置名称空间去查找。

示例如下:

1 x = 0
2 def input():
3     x = 1
4     print(x)
5 input()

#大家都知道python内置的一个方法叫做input( ),他是用来做用户交互的,但是如果我们自己定义一个input函数,
#那么再调用 input( )这个方法的时候,它会先从全局命名空间找input这个名字,如果找得到,那么它就不会再去
#内置名称空间去调用内置的input()方法了。而这个我们自定义的input方法内部有一个变量x,全局里还有一个变
#量也叫x,这个时候我们在函数内部调用x,那么解释器就会先从局部名称空间去找,很显然,它能找到,那么将不会再
#去全部或者内置名称空间里去找了,所以最后打印的x的值为1

五、作用域

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

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

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

六、global关键字和nonlocal关键字

△global

虽然在局部作用域内可以调用全局作用域的变量,但是它是没有权限修改,如果非要修改,那么就要用到global这个关键字了,如下:

1 a = 10
2 def func():
3     global a
4     a = 20
5 
6 print(a)  #调用函数之前a的值为10
7 func()
8 print(a)  #调用函数之后a的值就被修改为20了

△nonlocal

nonlocal关键字是用来改变外部离自己最近的局部变量

七、函数的嵌套

函数里面可以嵌套另外一个函数:

1 def outer(): 
2      def inner():
3          pass

八、闭包

满足一下两种情况的函数就成为闭包:

①有函数的嵌套

②内部函数调用外部函数的变量(不是指全局变量)

如下:

1 def outer():
2     a = 1
3     def inner():
4         print(a)

 九、闭包的应用

下面的例子是写一个简单的爬网页函数,将指定网页的源代码打印出来:

1 from urllib.request import urlopen
2 
3 def get_url():
4     url = 'http://www.xiaohua100.cn/index.html'
5     def get_html():
6         res = urlopen(url).read()
7         print(res)
8     get_html()
9 get_url()

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏鸿的学习笔记

python类的继承与运算符重载

Officially, CPython has no rule at all for when exactly overridden method of sub...

961
来自专栏函数式编程语言及工具

泛函编程(16)-泛函状态-Functional State

    初接触泛函状态觉着很不习惯。主要是在使用State数据类型时很难理解其中的原理,特别是泛函状态变迁机制(state transition mechani...

21110
来自专栏我的博客

JS闭包

在理解闭包以前.最好能先理解一下作用域链的含义,简单来说,作用域链就是函数在定义的时候创建的,用于寻找使用到的变量的值的一 个索引,而他内部的规则是,把函数自...

3155
来自专栏企鹅号快讯

Python数据结构

所属系列:【Python工程师系列】 所属主题:【Python零基础】 1 ? 编码格式建议 不用Tab缩进,用4倍空格缩进 必要时换行(避免单行超出79个字符...

2140
来自专栏GreenLeaves

C# static

本文,在大文豪的static与C#中的static随笔基础上修改,增加了几个关键知识点 1、static 关键字简介 static是C#中经常使用的关键字之一,...

1755
来自专栏LEo的网络日志

python技巧分享(十二)

1407
来自专栏蓝天

shell数组

$ A=(a b c def) ================================================== $ echo ${A[@...

1134
来自专栏前端之路

字符串、数组处理方法总结

1123
来自专栏企鹅号快讯

宝宝都能学会的python编程教程5:循环-2

“死循环”是必须要避免的,当然“活循环”也未必都要执行完。 break 语句 比如我们要从一个列表中找到某个特定元素,那么只要找到了这次循环就可以停止了,没有必...

2077
来自专栏鸿的学习笔记

随便写写python的特殊方法

还有__bool__,__abs__,__eq__,__str__进行重载,记得要注意在文档中说明

711

扫码关注云+社区

领取腾讯云代金券