[Python学习日记-32] Python 中的函数的返回值与作用域
简介
返回值
作用域
简介
在函数的介绍中我们提到了函数的返回值,当时只是做了简单的介绍,下面我们将会进行详细的介绍和演示,同时也会讲一下 Python 中的作用域,作用域分为全局和局部,这也会在下面进行详细讲解和演示。
返回值
函数外部的代码要想获取函数的执行结果,就可以在函数里用 return 语句把结果返回,代码如下
def stu_register(name, age, course='PY', country='CN'):
print("------注册学生信息------")
print("姓名:", name)
print("age:", age)
print("国籍:", country)
print("课程:", course)
if age > 22:
return False
else:
return True
registriation_status = stu_register('王老五',22,course='Python日记',country='JP')
if registriation_status:
print("注册成功")
else:
print("年龄过大")
代码输出如下:
当函数具有多个结果是则需要 return 多个值,代码如下
def stu_register(name, age, course='PY', country='CN'):
print("------注册学生信息------")
print("姓名:", name)
print("age:", age)
print("国籍:", country)
print("课程:", course)
if age > 22:
return False,"年龄过大"
else:
return True,"注册成功"
registriation_status,str = stu_register('王老五',22,course='Python日记',country='JP')
if registriation_status:
print(str)
else:
print(str)
代码输出如下:
注意:
- 函数在执行过程中只要遇到 return 语句,就会停止执行并返回结果,所以也可以理解为 return 语句代表着函数的结束
- 如果未在函数中指定 return,那这个函数的返回值为 None
作用域
一、全局与局部变量
函数中的作用域指的是变量的可访问范围。在函数内部定义的变量是局部变量,只能在函数内部被访问。在函数外部定义的变量是全局变量,可以在函数内部和外部被访问。代码如下
name = "Jove"
def change_name():
name = "浩南哥" # 局部变量,在这里相当于赋值了新的变量,只在函数里面有效
print("after change:",name," id:",id(name)) # 这里 print(name) 会先去找局部内存里的 name,如果没有才会去找全局内存里的 name
change_name()
print("在外面看看 name 改了没有:",name," id:",id(name))
代码输出如下:
在函数内部修改了 name 的值后,在外面 print() 的时候却没有修改,这是因为这两个 name 根本不是一回事,在上面的输出就可以看出函数内的内存地址和函数外面的内存地址是不一样的,局部变量和全局变量的注意事项如下
- 在函数中定义的变量称之为局部变量,在程序的一开始定义的变量称为全局变量;上面的代码中函数内的 name 称之为局部变量,外面的 name 称之为全局变量;
- 全局变量作用域(即有效范围)是整个程序,局部变量作用域是定义该变量的函数;
- 变量的查找顺序是局部变量 > 全局变量;
- 当全局变量与局部变量同名时,在定义局部变量的函数内,局部变量起作用;在其它地方全局变量起作用;
- 在函数里是不能直接修改全局变量的。
若是想在函数内修改全局变量那应该怎么修改呢?代码如下
name = "Jove"
def change_name():
global name # 在函数内部声明(创建)一个全局变量,如果全局变量在外面已经有了,更像是指向到外面的全局变量的内存地址
name = "浩南哥" # 这里调用的就是前面声明了的全局变量 name 了
print("after change:",name," id:",id(name))
change_name()
print("在外面看看 name 改了没有:",name," id:",id(name))
代码输出如下:
global name 的作用就是要在函数里声明(创建)全局变量 name,意味着最上面的 name="Jove" 即使不写,程序最后面的 print() 也可以打印 name。
值得注意的是,如果函数内声明了全局变量 name(global name)那 name = "浩南哥" 一定不能先于 global name,因为在你运行这段 Python 代码时,Python 解析器会先把这段代码读一遍,选出那些是局部变量,那些是全局变量,如果 name = "浩南哥" 先于 global name 那解析器会认为 name 既是局部变量也是全局变量,那就会出现如下报错信息
SyntaxError: name 'name' is assigned to before global declaration
二、传递列表、字典、集合产生的现象
d = {"name":"Jove","age":26,"hobbie":"大保健"} # 输出1841217292608
l = ["Rebeeca","Katrina","Rachel"] # 输出1841215033728
def change_data(staff_table,girls): # 这里 staff_table 和 girls 只是传递了字典和列表的内存地址进来,并没有像字符串那样在局部内存当中声明(创建)了新的变量
# 如果在函数当中创建了 dict,list 到函数结束时还是会销毁的
# 如果当函数当中出现了与全局变量同名的局部变量,那样会优先选择局部变量
# 在函数当中需要修改这个同名的变量,那样就要先声明这个临时变量,再操作,不然就会报错
print("传入函数中 d 的内存地址:",id(staff_table)) # 输出1841217292608
print("传入函数中 l 的内存地址:", id(girls)) # 输出1841215033728
staff_table["hobbie"] = "学习"
girls.append("XiaoYun")
change_data(d,l)
print("d:",d," ——> ",id(d),"\nl:",l," ——> ",id(l)) # 整个过程 d 和 l 的内存地址都没有发生过改变
代码输出如下:
可以看到代码输出当中 d 和 l 都已经发生了改变,这个怎么和前面我们得到的结果有这么大偏差呢?不是说不能在函数里改全局变量么,这里怎么改了呀?看了下面这张图你就明白了
根据上图我们能看出,程序只是把 d 这个 dict 的内存地址传给了 change_data 函数,把 dict 比作鱼缸,里面的 key 和 value 比作缸里装的鱼。现在只是把鱼缸丢给了函数,这个鱼缸本身你不能改,但是里面的鱼可以。相当于只是传了一个对这个 d 的引用关系给到函数的形参。这样是为了减少内存的浪费,因为如果这个 dict 比较大,传一次到函数里就要复制一份新的值的话,效率低不单止还极度浪费资源。