博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Python函数的返回值与嵌套函数
阅读量:6221 次
发布时间:2019-06-21

本文共 3896 字,大约阅读时间需要 12 分钟。

hot3.png

1.什么是返回值

  • 返回值指的是函数返回的结果;

  • return执行完毕后面的语句将不会再执行;

def add(x, y):    print(x, y)   #输出:10 20    return x + y   # 返回值, return以后的语句将不会再执行    print(x)    print(y)add(10,20)
  • 如果一个函数里面有两个return,前面return执行完毕,后面的return也不会执行;
def add(x, y):    print(x, y)    # 输出:1 2    return x + y   # 函数体内,碰到return语句,函数执行完毕,之后的语句将不会再执行    return x - y   # 不会再次执行add(1,2)

2.函数的隐式返回和显示返回

  • Python函数都有返回值,如果有return语句,是显式返回;

  • 如果没有return语句,默认返回None,是隐式返回;

3.函数多值返回

  • 如果返回多个值通过逗号分开,会把值进行压缩,封装成一个元组;
def get_data(x,y,z):    return x + 1, y + 1, z + 1print(get_data(1,2,3)) # 得到的是一个元组(2, 3, 4)
  • 如果返回一个列表,得到的就是一个列表;
def get_data(x,y,z):    return [x + 1, y + 1, z + 1]print(get_data(1,2,3))  # 得到的是一个列表[2, 3, 4]

4.什么是嵌套函数

def outer_function():    # 内部函数    def inner_function():        print("inner_function")  # 输出:inner_function    print("outer_function")      # 输出:outer_function    # 内部调用    inner_function()outer_function()# 注意:inner_function函数只能在outer_function函数内部调用,无法再outer_function函数外部被调用
  • 嵌套函数的内部函数只能在包含它的函数的直接父级调用,也就是只能在包含它的外部函数中调用;

  • 嵌套函数层数不宜过深,一般3层以内即可,太深不够直观,容易造成代码混乱;

5.函数作用域

  • 作用域指的是,一个标识符的作用范围就是这个标识符的作用域;

  • 在函数里面定义的变量(即局部作用域)只能在函数体内部被访问,函数外部不能访问;

def add(x, y):    z = 100    print(x, y , z)  #输出:1 2 100add(1,2)print(z)  #报错:NameError: name 'z' is not defined
  • 在函数外部定义的变量(即全局作用域)能在函数体外部被访问,也能在函数体内部被访问;
z = 100def add(x, y):    print(x, y, z)# 输出:1 2 100add(1, 2)print(z)  # 输出:100

6.函数的闭包

  • 闭包:内部函数引用了外部函数的变量,这就是闭包的定义;

  • 如果函数体想访问变量,只能在变量定义之后才能访问;

# 例1x=5def add():    y = x + 1    print(y)  #输出:6add()# 例2x=5def add():    x = x + 1  # 报错:local variable 'x' referenced before assignmentadd()# 报错原因分析:# 在例1中,函数内部引用的x为函数外部的x, 因此x的值为5# 在例2中,函数内部重新定义了x的值,那么整个函数内部都会使用这个内部x,# 因此在运算x + 1的时候,x还没有完成定义就被引用了,这里的x引用的一定是内部正在定义的 x,不是函数外部的 x=5这个x;# 例3:x=5def add():    print(x) # 这里的x引用的是x = 1的x,但是执行print(x)时,x还没有被定义,所以报错:local variable 'x' referenced before assignment    x =  1add()
  • 如果要访问函数体内部的函数,可以先把内部函数的函数名作为外部函数的返回值,把外部函数的引用赋值给变量,再调用变量;
# 例4:def outer_function():    x = 100    def inner_function():        print(x)        # 内部函数引用了外部函数的自由变量  输出:100    return inner_functionret = outer_function()ret()

7.关键字

  • global关键字:可以指定变量为全局变量,但是global关键字会污染全局变量,也就是会覆盖之前全局变量的值,所以最好慎用;
x=1def add():    global x  # 使用global关键字,指定x的引用全局的x变量    x = x + 1    print(x)  #输出:2add()x = 100def foo():    global x  # x被声明了全局变量    x = 10    x += 1    print(x)  # x的值为11foo()print(x)      # 输出x的值为:11,原本这里应该引用的是全局变量x = 100 的,因此global关键字污染了全局变量 x
  • nonlocal关键字:可以申明内部函数的变量引用的是外部函数变量的值(作用域在外部函数),不是全局作用域的值,因此不会污染全局作用域;
def outer_function():    x = 100    def inner_function():        x = x + 1       # 这样会报错,函数内部重新定义了x的值,但是还没有完成定义就被引用了        print(x)    return inner_functionret = outer_function()ret()def outer_function():    x = 1    def inner_function():        nonlocal x   # 使用nonlocal关键字声明x 为外层函数的x的值        x = x + 1    #所以这里使用的x 是外层函数的x        print(x)   #输出:2    return inner_functionret = outer_function()ret()

8.函数默认值的作用域

  • 同一个函数的生命周期相同,函数的默认值会绑定在函数的整个生命周期上,不会因为函数内部对默认值的操作而发生改变;
def add(lst = []):    lst.append('hello')    print(lst)add() # 输出:['hello']print('id={}'.format(id(add)))   # 函数对象的id值不变,调用的是同一个函数  id=1837000add() # 输出['hello', 'hello']print('id={}'.format(id(add)))   # 函数对象的id值不变,调用的是同一个函数  id=1837000# 查看函数的位置参数的默认值print(add.__defaults__)    #输出:(['hello', 'hello'],)# 查看函数的关键字参数的默认值print(add.__kwdefaults__)  #输出:None
  • 可以使用浅拷贝copy(简写[:])来清空默认值,那每次调用函数,默认值都为初始值;
def add(lst = []):    lst = lst[:]    lst.append('hello')    print(lst)add() # 输出:['hello']add() # 输出:['hello']
  • 也可以通过参数值判断来给默认值重新赋值,那每次调用函数,默认值都为初始值;
def add(lst=None):    if lst is None:        lst = []    lst.append(1)    print(lst)    add()    # 输出:[1]print(add.__defaults__)  # 输出: (None,)add([1, 2, 3])    # 输出: [1, 2, 3, 1]print(add.__defaults__)  # 输出:(None,)add([4, 5, 6])     # 输出:[4, 5, 6, 1]print(add.__defaults__)    # 输出:(None,)

9.函数销毁

def add():    print('add')del addadd()
  • 可以通过 del 函数名 的方式来删除函数,再调用函数时,就会报错不存在;

转载于:https://my.oschina.net/u/4072026/blog/3023813

你可能感兴趣的文章
深入下Ruby中的String
查看>>
Django 博客开发教程 4 - 让 Django 完成翻译:迁移数据库
查看>>
《Python密码学编程》——2.7 在线跟踪程序
查看>>
雾里看花之 Python Asyncio
查看>>
《树莓派Python编程入门与实战》——3.9 总结
查看>>
Velocity官方指南-使用Velocity
查看>>
jQuery获取数组对象的值
查看>>
从《一九八四》到《窃听风暴》
查看>>
《jQuery、jQuery UI及jQuery Mobile技巧与示例》——9.2 技巧:用单个HTML文件服务多张页面...
查看>>
360 for Linux 与 setuid
查看>>
《驾驭大数据》一3.5 电力行业:智能电网数据的价值
查看>>
《用户至上:用户研究方法与实践(原书第2版)》一2.5 特殊人群
查看>>
《OpenStack云计算实战手册(第2版)》——1.3 配置Ubuntu Cloud Archive
查看>>
《C#多线程编程实战(原书第2版)》——导读
查看>>
Java核心技术卷I基础知识1.5 关于Java的常见误解
查看>>
开源大数据周刊-第40期
查看>>
消息队列的exclusive consumer功能是如何保证消息有序和防止脑裂的
查看>>
云栖大会上宣布即将开源的手淘Atlas什么来头?
查看>>
将studio项目 转换为eclipse项目
查看>>
【Spark Summit EU 2016】在Spark集群中内置Elasticsearch
查看>>