10、Python基础之函数的调用与返回值

一、函数参数

1.1 不定长参数

当我们定义函数时,可能需要定义一个函数能处理比当初声明时更多的参数,这些参数叫做不定长参数。
我们可以在形参前面加上一个 * ,这样这个形参就可以获取所有的实参,它将所有的实参保存到一个元组中。
举例说明:
(1) 假如实参大于形参时,函数调用报错。

def fun(a, b):
    print(a + b)
fun(1,2,3)
------------------
fun() takes 2 positional arguments but 3 were given

(2) 不定长参数使用:

def fun(*a):  # 不定长参数
    print(a)
fun(1, 2, 3, 4)
----------------
(1, 2, 3, 4)
不定长参数特性:
(1) 位置传参的不定长参数
  1. 只能存在一个一个参数有 * 号,可以和其他的传参方式一起配合使用。但是位置参数不能放在不定长参数后面。
def fun1(*a, b):
    print(a)
    r = 0
    for i in a:
        r += i
    print(r)
fun1(1, 3, 5, 7)
----------------
执行错误:TypeError: fun1() missing 1 required keyword-only argument: 'b'

def fun1(b, *a):
    print(a)
    r = 0
    for i in a:
        r += i
    print(r)
fun1(1, 3, 5, 7)
-----------------
(3, 5, 7)
15
  1. 不定长参数要放在关键字传参前面
def fun1(c, *a, d):
    print(a)
    r = 0
    for i in a:
        r += i
    print(r)
fun1(1, 3, 5, d=9)
-------------------
(3, 5)
8
(2) 关键字传参的不定长参数
  • 2个 * 号表示关键字传参的不定长参数。
def fun1(**e):
    print(e)
fun1(a=1,  b=2, c=3, d=4)
-----------------
{'a': 1, 'b': 2, 'c': 3, 'd': 4}

特性:
位置传参必须放到不定长参数的前面,关键字传参必须要放到关键字传参的不定长参数之前:
格式:

def fun1(*g, h **e):
  print(e)
  print(g)
fun1(1, 2, a=1, b=2, c=3, d=4, h=1)
# h 负责接收关键字传参
# *g 负责接收位置传参
# **e 负责接收关键字传参的不定长参数
------------------
{'a': 1, 'b': 3, 'c': 5, 'd': 7}
1
(1, 2)
  • 位置传参的不定长参数 与 关键字传参的不定长参数混合使用时,也叫万能参数。
1.2 参数的拆包
  • 传递参数时,也可以在序列类型的参数前添加 "*" 号。这样它将会自动的将序列中元素依次作为参数传递。
  • 要求需要中的元素的个数必须和形参的个数一致。
    用,是不行的。
def fun(a, b, c):
    print(a)
    print(b)
    print(c)
tuple1 = (1, 3, 5)
fun(tuple1[0], tuple1[1], tuple1[2])

要传递元组中的数据时,上面的方式比较麻烦,那么有没有更简单的方式呢 ?

def fun(a, b, c):
    print(a)
    print(b)
    print(c)
tuple1 = (1, 3, 5)
fun(*tuple1)
----------------------
1
3
5

** 针对不定长参数,假如时一个字典时 ,参数拆包怎么使用呢 ?

dict1 = {'a': 1, 'b': 3, 'c': 5, 'd': 7}
def fun2(**dict1)

二、函数返回值 return

2.1 函数的返回值 《重点》

函数内的变量或者执行结果,想要直接到函数外面去使用,这样直接时无法使用的。因此,我们就需要把函数的的变量或者结果,放到外面去使用,这样就要借助于 return。

def fun(*args):
    r = 0
    for i in args:
        r += i
    print(r)

fun(1, 2, 3)
# print(r)
-----------------
print(r) 在函数内定义的,函数外时无法使用的。
函数的返回值 return
  • return r 只能返回 r 的值,而不能返回指定r 的名称。
def fun(*args):
    r = 0
    for i in args:
        r += i
    print(r)
    return r   # 返回了r 的值,但是外面不能使用r的名称。
fun(333, 444, 555, 666)
---------------------
1998
1998
  • return 返回值,可以定义任何数据类型:
    • return [1, 2, 3] <列表>
    • return True <bool 值>
    • return 1 <整型>
    • return {"a": 1, "b": 2, "c": 3}
    • return 后面不接数据时,返回 None。
def fun3(*args):
    r = 0
    for i in args:
        r += i
    #print(r)
    # return
    def fun4():
        pass
    return fun4    
res = fun3(11, 22, 33, 55)
print(res)
------------------------
<function fun3.<locals>.fun4 at 0x000001A4EDEF1C80>

函数没有定义 return 时,返回的也是None。

def fun3(*args):
    r = 0
    for i in args:
        r += i
res1 = fun3(11, 22, 33, 55)
print(res1)
------------------------
None
2.2 函数的调用 fun() 《重点》

函数的调用获得了函数的返回值的结果。
调用fun1()

res = fun()
print(res())
res()  #  res() 就是调用 fun() 函数。

结论:
1、 一个函数如果想要有返回值,必须写 return xxx。
如果没有return 和 只有一个return 没有任何返回的对象,那么这个函数的返回值就是None。

2、return 后面的代码都不再执行,看到 return 会直接退出函数。

def fun1():
      print(1)
      return  # return 后面的代码都不再执行,看到return直接退出函数。 
      print(2)
print(fun1())
2.2 函数的练习
def fun(*a):
    r = 0
    for i in a:
        r += i
    print(r)
    return a
print(fun(1+2, 3))
----------------------
6            # 调用函数的结果
(3, 3)       # 函数的返回值

分析:

  • fun() 表示函数的调用
  • fun(1+2, 3) 等于函数的返回值, 也就是 a 的值。

重点理解:

  1. 函数参数的传递
  2. 函数的调用 fun()
  3. 函数的返回值,即 return 返回的值,
  4. 函数的调用等于什么 ?a (函数的调用返回的是函数返回值的结果)
三、文档字符串
3.1 长字符串

作用: 保留文本的格式; 作位一个多行注释。
格式:"""xxx"""

"""
1) 保留文本的格式
2) 作位一个多行注释。
"""
3.2 文档字符串

作用: 对函数以及类进行说明作用及参数返回的一个文档说明。
例如 print() 函数

def print(self, *args, sep=' ', end='\n', file=None): # known special case of print
    """
    print(value, ..., sep=' ', end='\n', file=sys.stdout, flush=False)
    
    Prints the values to a stream, or to sys.stdout by default.
    Optional keyword arguments:
    file:  a file-like object (stream); defaults to the current sys.stdout.
    sep:   string inserted between values, default a space.
    end:   string appended after the last value, default a newline.
    flush: whether to forcibly flush the stream.
    """
    pass

四、作用域

  • 作用域(scope)
  • 作用域,是指变量生效的区域
  • python 中一共有2中作用域:全局作用域 和 函数作用域。
  1. 函数外部的区域都是全局作用域。
  2. 在全局作用域中定义的变量,都是全局变量,全局变量可以在任何地方使用。
  3. 函数的作用域在函数调用时创建,在调用结束后销毁。
a = 1
def fun():
    a = 10
    print(a)
fun()
print(a)
-------------
10   # 调用函数
1    # 全局变量

练习

  1. 用函数实现一个判断用户输入的年份是否为闰年的程序:
  • 能被400整除的年份
  • 能被4整除,但是不能被100整除的年份
    以上2种方法满足一种即为闰年。
def fun():
    while True:
        year = int(input("请输入年份:"))
        if year % 400 == 0 or (year % 4 == 0 and year % 100 != 0):
            print('%d是闰年' % year)
        else:
            print('%d不是闰年' %  year)
fun()
----------------
请输入年份:2000
2000是闰年
请输入年份:2001
2001不是闰年
请输入年份:2020
2020是闰年
请输入年份:
  1. 猴子吃桃问题(递归)
    猴子第一天摘下若干个桃子,当即吃了一半,还不过瘾,有多吃了一个,第二天早上又将剩下的桃子吃掉了一半,又多吃了一个,以后每天早上都吃了前一天剩下的一半零一个。到了第10天早上想再吃时,见到只剩下一个桃子了,请问一共摘了多少个 桃子 ?

思路:

  1. 假设总共x 个桃子,每天吃一半多吃一个,那第二天剩下:x/2-1.
  2. 依次递减,到第10天为1个,可以反过来思考,设置一个队列,令对列从右到左取值,索引为-1的元素=1,然后前一个索引对应的元素则为 (x+1)*2
  3. list.insert(index, (x+1) * 2),到第10个索引对应的的值,即list[0]对应的值就是第一天摘的桃子总数
def fun1():
     i = -1
     x = 1
     list1 = []
     while i >= -10:
         if i == -1:
             list1.append(x)
             #print(list1)
             i = i - 1
         if i < -1:
            x = (x+1) * 2
            list1.insert(i-1, x)
            i = i-1
     print(list1)
     return x
print('猴子一共摘了%d个桃子' % fun1())
-------------输出--------------
[1534, 766, 382, 190, 94, 46, 22, 10, 4, 1]
猴子一共摘了1534个桃子
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • 1.什么是返回值 1)返回值的作用: 将函数里面的数据传递到函数外面 2)初学怎么确定需不需要返回子: 看函数的功...
    臨時人間阅读 77评论 0 0
  • 一、函数的返回值 1.什么是返回值 1). 返回值的作用: 将函数里面的数据传递到函数外面2). 初学怎么确定需不...
    穷到没有姓名阅读 324评论 0 1
  • 1. 什么是函数 函数是对实现某一特定功能的代码块的封装 2. 函数的分类 系统函数(内置函数)-- 系统已经实现...
    XXXXStone阅读 135评论 0 0
  • 1.什么是函数 函数就是对实现某一特定功能的代码段的封装 2.函数的分类 内置函数(系统函数): python已经...
    Z_JoonGi阅读 753评论 0 0
  • 01 recode 1. 函数的声明(声明函数的时候不会执行函数体) 参数列表中的阐述可以进行参数类型说明(只是进...
    EryangZ阅读 171评论 0 0