Python——函数入门(三)
一、变量作用域
当程序定义一个变量时,这个变量是有它的作用范围的,变量的作用范围称为变量的作用域。根据变量的位置,分为两种:
- 局部变量:局部变量就是在函数中定义的变量,包括参数,都是局部变量,局部离开函数后,将不能被访问。
- 全局变量:不在函数内定义、全局范围内定义的变量,都是全局变量,全局变量可以在所有函数中被访问。
在Python中,提供了三个工具函数获取指定范围内变量和值组成的字典。
- globals():返回当前作用域全局变量的字典;无论在哪里使用,都会获取全局变量。
- locals():返回包含当前范围的局部变量的字典;当在全局范围内使用,会获取全局范围内所有变量组成的字典。
- vars():当没有参数时,相当于locals();有一个参数时,相当于object.__dict__。
使用globals()和locals()获取全局变量时,不应该被修改,修改会改变全局变量本身。而locals()获取局部变量时,即使修改了,也不会对局部变量产生影响。
globals(),例:
- a = 1
- def test():
- b = 2
- print (globals())
- test()
- # 打印全局变量 {'__name__': '__main__', '__doc__': None, '__package__': None, '__loader__': <class '_frozen_importlib.BuiltinImporter'>, '__spec__': None, '__annotations__': {}, '__builtins__': <module 'builtins' (built-in)>, 'a': 1, 'test': <function test at 0x0000000002EAC1E0>}
- globals()
- # 打印全局变量 {'__name__': '__main__', '__doc__': None, '__package__': None, '__loader__': <class '_frozen_importlib.BuiltinImporter'>, '__spec__': None, '__annotations__': {}, '__builtins__': <module 'builtins' (built-in)>, 'a': 1, 'test': <function test at 0x0000000002EAC1E0>}
locals(),例:
- a = 1
- def test():
- b = 2
- print (locals())
- test()
- # 打印局部变量 {'b': 2}
- print (locals())
- # 打印全局变量 {'__name__': '__main__', '__doc__': None, '__package__': None, '__loader__': <class '_frozen_importlib.BuiltinImporter'>, '__spec__': None, '__annotations__': {}, '__builtins__': <module 'builtins' (built-in)>, 'a': 1, 'test': <function test at 0x0000000002EAC1E0>}
vars(),例:
- class test01:
- k1 = 1
- def test02():
- k2 = 2
- print (vars())
- k3 = 3
- test01.test02()
- # 打印test02()的局部变量 {'k2': 2}
- print (vars())
- # 打印全局变量 {'__name__': '__main__', '__doc__': None, '__package__': None, '__loader__': <class '_frozen_importlib.BuiltinImporter'>, '__spec__': None, '__annotations__': {}, '__builtins__': <module 'builtins' (built-in)>, 'test01': <class '__main__.test01'>, 'k3': 3}
- print (vars(test01))
- # 打印类的属性 {'__module__': '__main__', 'k1': 1, 'test02': <function test01.test02 at 0x00000000023892F0>, '__dict__': <attribute '__dict__' of 'test01' objects>, '__weakref__': <attribute '__weakref__' of 'test01' objects>, '__doc__': None}
- print (test01.__dict__)
- # 打印类的属性 {'__module__': '__main__', 'k1': 1, 'test02': <function test01.test02 at 0x00000000023892F0>, '__dict__': <attribute '__dict__' of 'test01' objects>, '__weakref__': <attribute '__weakref__' of 'test01' objects>, '__doc__': None}
全局变量虽然可以被所有函数访问,但是如果在函数内定义了与全局变量同名的变量,就会发生局部变量遮蔽全局变量的情况,例:
- a = 1
- def test():
- print (a)
- test()
- # 运行成功,打印 1
- def test02():
- a = 2
- print (a)
- test02()
- # 函数内部对不存在的变量赋值,会重新定义新的局部变量,打印 2
- def test03():
- print (a)
- a = 3
- test03()
- # 报错UnboundLocalError: local variable 'a' referenced before assignment,由于a=3这段代码重新定义了局部变量,所以a全局变量被遮蔽。
二、使用global语句在函数中声明全局变量
为了避免在函数中对全局变量赋值,可以通过global语句声明全局变量。
例:
- a = 1
- def test():
- # 声明a是全局变量,后面的语句将不会重新定义局部变量
- global a
- print (a) # 打印 1
- # 对全局变量进行赋值
- a = 2
- test()
- # 打印 1
- print (a)
- # 打印 2
三、局部函数
前面我们看到的都是全局函数,我们还可以在函数体内定义函数,这称为局部函数,局部函数在默认情况下,对外部是隐藏的,只能在其封闭函数内有效,如果想在其他作用域中使用局部函数,其封闭函数可以返回局部函数。
例:
- # test()函数根据不同的参数,选择调用不同的局部函数
- def test(x):
- def a(x):
- return x * x
- def b(x):
- return x
- if x != 0:
- return a(x)
- else:
- return b(x)
- print (test(2))
- # 打印 4
- print (test(0))
- # 打印 0
局部函数的变量也会遮蔽他所在函数的局部变量,例:
- def test01():
- a = 1234
- def test02():
- print (a)
- a = 4321
- test02()
- test01()
- # 报错 UnboundLocalError: local variable 'a' referenced before assignment
上面的代码中,由于在test02()函数中重新定义了新的局部变量a,test02()函数中定义的局部变量a遮蔽了他所在函数test01()中的局部变量a,我们可以通过nonlocal语句声明访问赋值语句只是访问该函数所在函数的局部变量。
注意,nonlocal语句只能在嵌套函数中使用,并且在外层函数中必须定义了相关的局部变量,否则会报错。
例:
- def test01():
- a = 1234
- def test02():
- nonlocal a # 声明a是test01()的局部变量
- print ('01',a)
- a = 4321 # 改变外层函数局部变量的值
- print ('02',a)
- print ('03',a)
- test02()
- print ('04',a)
- test01()
- # 打印
- # 03 1234
- # 01 1234
- # 02 4321
- # 04 4321
Python——函数入门(三)的更多相关文章
- 3.Python爬虫入门三之Urllib和Urllib2库的基本使用
1.分分钟扒一个网页下来 怎样扒网页呢?其实就是根据URL来获取它的网页信息,虽然我们在浏览器中看到的是一幅幅优美的画面,但是其实是由浏览器解释才呈现出来的,实质它是一段HTML代码,加 JS.CSS ...
- 转 Python爬虫入门三之Urllib库的基本使用
静觅 » Python爬虫入门三之Urllib库的基本使用 1.分分钟扒一个网页下来 怎样扒网页呢?其实就是根据URL来获取它的网页信息,虽然我们在浏览器中看到的是一幅幅优美的画面,但是其实是由浏览器 ...
- python函数入门到高级
函数的定义: def test(x): "The function definitions" x+=1 return x def:定义函数的关键字 test:函数名 ():内可定义 ...
- Python函数(入门6)
转载请标明出处: http://www.cnblogs.com/why168888/p/6407970.html 本文出自:[Edwin博客园] Python函数 1. Python之调用函数 pri ...
- RobotFramework + Python 自动化入门 三 (Web自动化)
在<RobotFramwork + Python 自动化入门 一>中,完成了一个Robot环境搭建及测试脚本的创建和执行. 在<RobotFramwork + Python 自动化入 ...
- Python 函数(三)
Python 3 函数 (闭包.装饰器.递归.高阶函数) 一.闭包 内部函数可以引用外部函数的参数和局部变量,当外部函数返回内部函数时,相关参数和变量 都保存在返回的函数中,简单的说,这种内部函数可以 ...
- python函数入门
知识内容: 1.函数的作用 2.函数的定义与调用 3.函数的返回值 4.函数的参数 5.局部变量与全局变量 6.作用域 一.函数的作用 1.复用代码 将可能重复执行的代码封装成函数,并在需要执行的地方 ...
- Python——函数入门(一)
一.理解函数 举一个例子,当我们需要重复使用一个功能的时候,不可能每次都去复制一次代码,这个时候就需要用到函数了,所谓的函数,简单来说就是给函数取一个名字,当需要用到这个功能的时候,就可以通过这个名字 ...
- Python——函数入门(二)
一.函数的参数 我们在定义函数时,可以定义形式参数(简称形参),这些形参的值在函数调用的时候才会确定,形参的值由调用者负责传入. 1.关键字参数 在Python中,函数的参数名并不是没有意义的,在调用 ...
随机推荐
- spark 机器学习 朴素贝叶斯 实现(二)
已知10月份10-22日网球场地,会员打球情况通过朴素贝叶斯算法,预测23,24号是否适合打网球.结果,日期,天气 温度 风速结果(0否,1是)天气(0晴天,1阴天,2下雨)温度(0热,1舒适,2冷) ...
- 前后分离调用API跨域
前后分离调用API接口跨域问题 什么是跨域? 跨域是指一个域下的文档或脚本试图去请求另一个域下的资源,这里跨域是广义的. 广义的跨域: 资源跳转:A链接.重定向.表单提交. 资源嵌入: <li ...
- spark sql metastore 配置 mysql
本文主要介绍如何为 spark sql 的 metastore 配置成 mysql . spark 的版本 2.4.0 版本 hive script 版本为 hive 1.2.2 mysql 为 5. ...
- [USACO09OCT]热浪Heat Wave Dijkstra
题目描述 The good folks in Texas are having a heatwave this summer. Their Texas Longhorn cows make for g ...
- 2018年12月25&26日
小结:昨天因为整理课件,调代码耗费了大量时间,所以没来得及整理作业,这两天主要做的题目是关于树链剖分和线段树的,难度大约都是省选难度,毕竟只要涉及到树链剖分难度就肯定不低. 一. 完成的题目: 洛谷P ...
- npm install 权限问题
npm ERR! Error: EACCES: permission denied, access '/Users/Lobin/work/note-vue/node_modules/@babel/hi ...
- Java中文编程开发,让Java编写更改复杂
额?what? 在B站无意中看到一张图,无意间已发了自己的好奇,实际上我早就知道Java支持Unicode编码也就是可以使用中文命名规则,但是我们可以包装一下,玩一玩完全使用中文编码也未尝不可,但是经 ...
- Command模式(命令设计模式)
Command?? 把方法的调用用一个类的实例来承载,要管理工作的历史记录,创建这些方法执行的命令的集合,只需管理这些实例的集合即可,而且还可以随时再次执行过去的命令,或是将多个过去的命令整合为一个新 ...
- 注意sqlite3和java的整数数据类型的区别
作为新手的我,没有考虑数据库和java的数据类型的对应上的区别: sqlite3的数据类型和java数据类型对应上要小心,特别是整数类型. java 中int类型4位存储,范围 -2^31到2^31- ...
- 工厂模式 jdbc 面向接口dao 开发 单例
package com.itheima.utils; import java.io.IOException; import java.io.InputStream; import java.util. ...