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. docker 小结

    1.docker修改镜像地址: /etc/docker/daemon.json 2.docker 启动容器: docker run -t -i ubuntu:14.04 /bin/bash 3.查看容 ...

  2. 八(第三篇)、主体结构元素——time元素、pubdate属性

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  3. python3文件的读写操作

    open函数:对文件进行读写操作前,先打开文件,获取文件的句柄: open(file, mode, encoding, buffering) 参数说明 file_name:一个包含了你要访问的文件路径 ...

  4. gentoo 工具命令

    查看具体某个命令来源于哪个软件包,使用 equery,比如说查找 lsusb 来源于哪个包,可以用 equery belongs lsusb

  5. spring boot 接口用例测试

    接口: 测试用例:

  6. shell:实现linux服务器资源监控并发送告警邮件

    1.安装方式 wget http://10.8.225.126/wsmonitor/install.sh;sh install.sh test@test.com 2.install.sh #!/bin ...

  7. WinForm c#操作Excel

    1)Excel 的 Range 对象 在可以对 Microsoft Office Excel 2003 中的任何范围执行操作前,必须将其表示为 Range 对象并使用此 Range 的方法和属性.Ra ...

  8. python Django 无法获取post 参数问题

    对于 request.POST.get(name) 方式取值,需要 from 表单提交数据,如果 是ajax 提交数据,则需要做如下设置: 1.设置请求头,以from表单方式传值 'Content-T ...

  9. proposal-cancelable-promises

    fetch 从来就没行过,最大的优势就是"新标准",但是 proposal-cancelable-promises 被 withdrawn,就导致了 fetch 发起的请求不可能被 ...

  10. Communication Model

    [Communication Model] EOSIO actions operate primarily in a message-based communication architecture. ...