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. Letsencrypt SSL免费证书申请(Docker)

    最近需要SSL证书,又不想花钱买,正好看到linux基金会去年底上线了新的开源项目,免费推广SSL遂尝试. Let's Encrypt 介绍 Let’s Encrypt is a free, auto ...

  2. 涂抹mysql笔记-InnoDB/MyISAM及其它各种存储引擎

    存储引擎:一种设计的存取和处理方式.为不同访问特点的表对象指定不同的存储引擎,可以获取更高的性能和处理数据的灵活性.通常是.so文件,可以用mysql命令加载它. 查看当前mysql数据库支持的存储引 ...

  3. java中随机二维数组中寻找最大值并输出坐标

    public static void main(String[] args) { int x=0; int y=0; int a[][]=new int[5][5]; int max=-Integer ...

  4. 工具函数(获取url , 时间格式化,随机数)

    (function(window,$){ function Tools() { } // url Tools.prototype.readUrlToParams = function() { var ...

  5. wireshark抓本地回环包

    问题描述: 在网络程序开发的过程中,我们往往会把本机既作为客户端又作为服务器端来调试代码,使得本机自己和自己通信.但是wireshark此时是无法抓取到数据包的,需要通过简单的设置才可以 方法一:Wi ...

  6. Python:笔记1_字符串处理【转载】

    [转载自:https://www.cnblogs.com/houht/p/3308634.html] 1. 判断字符串str是否为空Approach 1:如果字符串长度为0,说明字符串为空,code如 ...

  7. zabbix4.0下zabbix-agentd安装

    转:http://www.safecdn.cn/monitor/2018/12/zabbix4-0-zabbix-agentd-install/316.html 一 安装源和Zabbix的依赖包: 1 ...

  8. 201772020113李清华《面向对象程序设计(java)》第一周学习总结

    201772020113<面向对象程序设计(java)>第一周学习总结 第一部分:课程准备部分 填写课程学习 平台注册账号, 平台名称 注册账号 博客园:www.cnblogs.com b ...

  9. leetcode297

    public class Codec { // Encodes a tree to a single string. public string serialize(TreeNode root) { ...

  10. Innodb锁相关总结

    一.InnoDB共有七种类型的锁: (1)共享/排它锁(Shared and Exclusive Locks) (2)意向锁(Intention Locks) (3)插入意向锁(Insert Inte ...