python函数(二)

变量的作用域

1、局部变量与全局变量

在函数内创建的变量被称为局部变量,这类变量的生命周期与函数相同,当函数执行完毕时,变量也就随之消失。

此类变量只能在函数内部调用,函数外不能调用该变量。

def getName():
name = 'Jerry'
print('函数getName()中的name:' + name) getName()
# print(name) 在函数外引用函数内定义的name变量,就会直接报错:NameError: name 'name' is not defined

打印结果:

函数getName()中的name:Jerry

全局变量是定义在函数之外的变量,该函数在函数内外都可以调用。全局变量作用域是整个程序,局部变量作用域是定义该变量的子程序(函数)。

NAME = 'Serra'

def getName():
print('在函数内调用全局变量NAME:' + NAME) getName()
print('在函数外调用全局变量NAME:' + NAME)

打印结果:

在函数内调用全局变量NAME:Serra
在函数外调用全局变量NAME:Serra

2、存在同名的全局变量与局部变量

变量调用的基本规则就是:python总是会去寻找距离最近的声明变量。这种距离最近不是上下文的距离,而是在调用变量时,在当前作用域寻找声明变量,如果没有,则向上一层寻找声明变量,直至找到该名称的变量。

name = 'global name'

def outer():
name = 'outer name'
def inner1():
name1 = 'inner name'
def inner2():
print('在Inner2函数中找到的name是:' + name)
return inner2
return inner1 outer()()()

打印结果:

在Inner2函数中找到的name是:outer name

在上述例子中,outer函数内嵌套着inner1函数,inner1函数内又嵌套着inner2函数。inner1函数将inner2函数作为返回值,outer函数将inner1函数作为返回值。

这个函数的调用过程如下:

  • outer(),返回值为inner1,此时的返回值是一个inner1函数;
  • outer()(),相当于调用outer函数中的inner1函数,此时inner1函数的返回值为inner2函数,到这一步我们获得的是inner2函数;
  • outer()()(),相当于调用上一步获得的inner2函数,得到打印结果。

从这个例子中可以看到,在调用变量时,程序会一层层地向上查找,直到找到相应名称的变量。

3、global与nonlocal关键字

在一般的变量调用中,修改函数内部定义的变量,对同名的全局变量并不会产生影响。

name = 'global name'

def bar():
name = 'bar\'s name'
print('函数内的name:' + name) bar()
print('函数外的name:' + name)

打印结果:

函数内的name:bar's name
函数外的name:global name

可以看到,在函数内修改name的值,这种修改只限于在调用函数时;当函数执行完毕后,调用的name变量的值依然没有改变。

但是python中提供了global关键字,该关键字用于函数内部,引用形式:'global 变量名'。使用该关键字时,表示函数内部引用的是全局变量。

name = '全局变量中定义的name...'

def foo():
global name
name = 'foo\'s name' foo()
print('调用foo()后,全局变量中定义的name:' + name)

打印结果:

调用foo()后,全局变量中定义的name:foo's name

可以看到,使用了global关键字后,foo函数修改的name就是全局变量中的name了。

在函数中出现了global关键字后,这之后的变量指向的都是全局中的变量。因此,函数如果有自己的私有变量(局部变量)时,不要和global变量重名,否则会使调用出现错误;global关键字要写在函数体的最开始部分。

无论在函数内部定义了多少层函数,global关键字命名的变量永远指向全局变量。

此外,python还提供了一个nonlocal关键字,用来在内部函数调用外层函数的变量。

def foo():
name = 'foo\'s name...'
def bar():
nonlocal name # 使用nonlocal关键字调用foo函数中的name变量
name = '更名为:bar\'s name...' # 此时修改的是foo中的name变量
bar() # 在foo()函数内部调用bar()
print(name) foo()

打印结果:

更名为:bar's name...

可以看到,在foo函数内部定义了一个bar函数,nonloca name这一句表示调用的是bar函数外层、也就是foo函数的name变量,并在bar函数内部对该变量的值进行了修改。在foo中运行bar函数,调用foo的同时也调用了内部的bar函数。因此输出的name就变成了更改过的值。

需要注意的一点:nonlocal关键字仅能调用函数外层的局部变量,不能调用全局变量。有人会问,既然nonlocal关键字能够调用外层变量,那么当函数外层只有全局变量时,能否用nonlocal调用全局变量呢?

name = 'global name'

def foo():
nonlocal name
name = 'foo\'s name' print('当前的name:' + name)

无打印结果,程序会报错:无nonlocal变量绑定

SyntaxError: no binding for nonlocal 'name' found

nonlocal并不能调用全局变量。

python函数(二)的更多相关文章

  1. python初步学习-python函数 (二)

    几个特殊的函数(待补充) python是支持多种范型的语言,可以进行所谓函数式编程,其突出体现在有这么几个函数: filter.map.reduce.lambda.yield lambda >& ...

  2. python学习【第五篇】python函数 (二)

    一.装饰器 装饰器:本质就是函数,功能是为其它函数添加附加功能 装饰器的原则: 不修改被修饰函数的源代码 不修改被修饰函数的调用方式 装饰器的知识储备: 装饰器 = 高阶函数 + 函数嵌套 + 闭包 ...

  3. Python 函数(二)

    参数 以下是调用函数时可使用的正式参数类型: 必备参数 关键字参数 默认参数 不定长参数 必备参数 必备参数须以正确的顺序传入函数.调用时的数量必须和声明时的一样. 调用printme()函数,你必须 ...

  4. Python函数二(函数名,闭包,迭代器)之杵臼之交

    函数名的使用: 函数名可以作为值,赋值给变量. 函数名可以作为参数传参给函数. 函数名可以作为返回值. 函数名可以作为元素存储在容器里. 闭包:在嵌套函数内,使用外层局部变量(非全局变量)就是一个闭包 ...

  5. Python函数(二)-参数传递

    位置参数 根据位置顺序来传递参数 # -*- coding:utf-8 -*- __author__ = "MuT6 Sch01aR" def test(a,b): #a和b为形参 ...

  6. PYTHON练习题 二. 使用random中的randint函数随机生成一个1~100之间的预设整数让用户键盘输入所猜的数。

    Python 练习 标签: Python Python练习题 Python知识点 二. 使用random中的randint函数随机生成一个1~100之间的预设整数让用户键盘输入所猜的数,如果大于预设的 ...

  7. python之内置函数(二)与匿名函数、递归函数初识

    一.内置函数(二)1.和数据结构相关(24)列表和元祖(2)list:将一个可迭代对象转化成列表(如果是字典,默认将key作为列表的元素).tuple:将一个可迭代对象转化成元组(如果是字典,默认将k ...

  8. 二. python函数与模块

    第四章.内置函数与装饰器详解 1.内置函数补充1 注:红色圆圈:必会:  紫红色方框:熟练:   绿色:了解 callable() 判断函数是否可以被调用执行 def f1(): pass f1() ...

  9. Python进阶(二)----函数参数,作用域

    Python进阶(二)----函数参数,作用域 一丶形参角度:*args,动态位置传参,**kwargs,动态关键字传参 *args: ​ 动态位置参数. 在函数定义时, * 将实参角度的位置参数聚合 ...

随机推荐

  1. centos 全局环境变量设置

    CentOS的环境变量配置文件体系是一个层级体系,这与其他多用户应用系统配置文件是类似的,有全局的,有用户的,有shell的,另外不同层级有时类似继承关系.下面以PATH变量为例. 1.修改/etc/ ...

  2. pygame 简单播放音乐程序

    环境: python2.7 pygame 功能: 播放指定目录下的歌曲(暂时mp3),可以上一曲.下一曲播放. 文件目录: font  字体文件夹 image  图片文件夹 music  音乐文件夹 ...

  3. Python有趣时刻,这些代码让你大呼"卧槽,怎么会这样"

    分享一个实用问题,用python读取Excel并保存字典,如何做? 下面是该同学问题截图和代码 image.png 代码截图是下面这样的 image.png 不知道大家第一眼看了这个代码,什么感受?我 ...

  4. dll 恐怖的代码调整

    总结一波这998的不得不提的调整代码的心得. 调整代码的背景:现有wps美化代码分散在各个插件里面,导致每次修改一小部分代码,都要全新编译,并且只能跟版本发,所以决定将wps的美化代码整合成一个插件d ...

  5. android 开发 View _13 绘制图片与BitmapShader位图的图像渲染器

    BitmapShader位图的图像渲染器 TileMode 模式 Shader.TileMode.CLAMP 边缘拉伸. Shader.TileMode.MIRROR 在水平方向和垂直方向交替景象, ...

  6. nginx gunicorn 部署flask,带参数链接不可用的现象(笔记)

    微信小程序后台,开启 gunicorn之后屏幕会输出打印结果,一旦关闭shell 带参数链接不可用,只有开启shell才能使用, 一针见血 : 注释掉所有print语句,关闭shell 带参数的链接  ...

  7. django admin 设置(转载https://www.cnblogs.com/wumingxiaoyao/p/6928297.html)

    Django admin 一些有用的设置   Django自带的后台管理是Django明显特色之一,可以让我们快速便捷管理数据.后台管理可以在各个app的admin.py文件中进行控制.以下是我最近摸 ...

  8. XSLT 创建CDATA节点

    创建文本结点 (1)直接写入文本: text1 (2)通过<xsl:text>创建文本结点: <xsl:text>text2</xsl:text> (3)通过< ...

  9. HttpRunnerManager安装部署

    uname -a cat /etc/redhat-release 1.安装docker.mysql.rabbitmq sudo yum update curl -fsSL https://get.do ...

  10. c++ 中的智能指针实现

    摘要:C++11 中新增加了智能指针来预防内存泄漏的问题,在 share_ptr 中主要是通过“引用计数机制”来实现的.我们今天也来自己实现一个简单的智能指针: // smartPointer.cpp ...