python 基础语法之函数

python基础语法 之 函数

  • 函数
  • 函数的参数
  • 函数的返回值
  • 函数的嵌套
  • 函数变量作用域
  • 函数参数
    • 位置参数详解:
    • 关键字参数:
    • 缺省参数
    • 不定长参数
  • 匿名函数
  • 总结

函数

  • 概述:函数也叫方法,可以用单词Function(函数,功能),Method(方法)来表示.
  • 定义格式:
 def 函数名(形式参数1,...)
	函数体,以前书写的逻辑代码,if,for...
	return 具体返回值
  • 格式解释:
    • def defined单词的缩写, 表示: 定义1个函数.
    • 函数名 方便我们调用函数的, 起名时最好做到 见名知意. get_max(), get_sum()
    • 形参参数 简称叫: 形参, 形容调用函数需要传入什么值.
    • 函数体 表示该函数要完成什么功能, 就是以前我们写的逻辑代码, if, for…
    • return 作用1(主职): 结束函数的. 作用2(兼职): 可以返回函数的执行结果.
  • 调用的格式:
    1.写函数名
    2,传参
    3.接受返回值 如果有的话
  • 注意
    1.函数先定义,才能被调用
    2.只有被调用才会执行
# 定义函数, 表示: 打电话.
def call():
   print('----- 拨号 -----')
   print('(拨号方)手机发送信号包到 就近的基站')
   print('(拨号方)就近的基站 解析信号包, 然后通过地下电缆 发送信号包到 接收方就近的基站')
   print('(接收方就近的基站 发送信号包 到 (接收方)手机')
   print('(接收方)手机解析信号包...')
   print('(接收方)盲音等待 ...')
# 具体的打电话动作.
call()
  • 函数说明文档
"""
函数的说明文档介绍:
   概述:
       你可以理解为就是函数的 注释, 帮助程序员快速认识函数的作用的.
   格式:
       在函数内部的第一行, 直接用 三引号包裹即可.
"""
# 需求: 定义函数 get_sum(a, b), 求两个整数的和.

def get_sum(a, b):
   """
   自定义函数, 用于计算 两个整数的 和
   :param a: 要求和计算的第1个整数
   :param b: 要求和计算的第2个整数
   :return: 返回a和b的 求和结果
   """
   sum = a + b
   return sum


sum = get_sum(10, 20)
print(f'求和结果为: {sum}')
print('-' * 30)

# 也可以查看函数的说明文档.
help(get_sum)

函数的参数

  • 1.写法:根据参数和返回值不同分为
    • 1.无参无返回值
    • 2.有参无返回值
    • 3.无参有返回值
    • 4.有参有返回值
    1. 定义函数的时候, 写的参数列表叫: 形参, 形容调用函数, 需要传入什么值.
    1. 调用函数的时候, 写的参数列表叫: 实参, 表示调用函数时, 实际参与运算的数据.
    1. 函数只有被调用, 才会执行.
需求1: 定义函数 get_sum(), 用于计算两个整数和, 并打印结果.
# 写法1: 无参无返回值.
def get_sum():
   sum = 10 + 20
   print(f'求和结果为: {sum}')
   return  # 方法的最后一行, 默认都有1个return, 表示结束方法, 并默认返回None
# 调用函数.
get_sum()
print('-' * 30)
# 写法2: 有参无返回值.    因为上述的函数只能计算整数 10 和 20的求和结果, 不够灵活.
def get_sum2(a, b):     # a,b充当的作色是 形参.
   """
   自定义函数, 用于计算 两个整数和.
   :param a: 求合计计算用到的第 1个整数
   :param b: 求合计计算用到的第 2个整数
   :return: 空
   """
   sum = a + b
   print(f'求和结果为: {sum}')
   return  # 方法的最后一行, 默认都有1个return, 表示结束方法, 并默认返回None 打印求和结果.

# 调用函数.
get_sum2(1, 2)      # 1 和 2在这里充当的是: 实参(实际参数)
get_sum2(10, 20)    # 10 和 20在这里充当的是: 实参(实际参数)

print("-" * 30)
# 需求2: 定义函数, 完成 前两个数求和, 对第3个数进行减法运算, 调用, 并测试该函数.
def get_sum3(a, b, c):      # 形参.
   """
   自定义函数, 完成 n1 + n2 - n3的
   :param a: 要求和的第1个数
   :param b: 要求和的第2个数
   :param c: 进行减法运算的数字
   :return: 无
   """
   result = a + b - c
   print(result)
# 调用 get_sum3()函数
get_sum3(10, 20, 5) # 实参(实际参与运算的数字), 25.

函数的返回值

  • 概述:
    返回值指的是 函数执行完毕后, 需要返回给 调用者一个什么样的结果.
  • 格式:
    在函数内部写, return 具体的返回值即可.
  • 需求:
    定义get_sum(), 用于计算两个整数和.
  # 需求: 定义get_sum(), 用于计算两个整数和.
# 1. 定义get_sum()函数.
def get_sum(a, b):      # a, b 形参, 形容调用函数, 需要传入是什么样的值.
    """
    自定义函数, 计算两个整数的和.
    :param a: 求和运算的第1个整数
    :param b: 求和运算的第2个整数
    :return: 求和结果.
    """
    # 具体的求和过程
    sum = a + b
    # 返回求和结果
    return sum
    # 2. 调用函数.
sum = get_sum(10, 20)
print(f'求和结果为: {sum}')

案例: 演示 函数返回值 作为 参数传递.

# 1. 定义函数, 返回1个整数.
def get_number():
    return 30


# 2. 定义函数, 传入1个整数, 判断其奇偶性.
def is_odd(n):
    if n % 2 == 0:
        print(f'{n} 是偶数!')
    else:
        print(f'{n} 是奇数!')


# 3. 测试上述的函数.
if __name__ == '__main__':
    # 分解版写法
    # 3.1 获取整数
    n = get_number()        # n = 30

    # 3.2 把 n(1个函数的返回值)  作为 is_odd()函数的参数进行传递.
    is_odd(10)
    is_odd(11)
    is_odd(n)
    print('-' * 30)

    # 合并版.
    is_odd(get_number())        # 细节: 函数的返回值, 可以作为另一个函数的参数.
    print('-' * 30)


    # 拔高, 函数名 可以作为 对象使用.
    # n = get_number()        # 函数名() 表示在 调用函数.
    my_fun = get_number       # 函数名, 可以作为对象使用. 即: 现在写 my_fun() 和 get_number() 是一样的.
    n = my_fun()
    print(n)        # 30


函数返回多个结果: 会把多个结果 封装成1个元组进行返回.
```python
思考: 1个函数可以同时返回多个结果(返回值)?
答案: 错误, 因为1个函数只能返回1个结果, 如果同时返回多个值则会封装成1个元素进行返回.
"""

# 需求: 定义函数 my_calculate(a, b), 返回两个整数的: 加减乘除结果.
def my_calculate(a, b):
    add = a + b
    sub = a - b
    mul = a * b
    div = a // b
    # return add, sub, mul, div   # 如果函数同时返回多个结果, 则会封装到1个元组中, 进行返回.
    return add, sub, mul, div   # 如果函数同时返回多个结果, 则会封装到1个元组中, 进行返回.


# 测试函数
if __name__ == '__main__':
    result = my_calculate(10, 3)
    print(type(result)) # 
    print(result)

函数的嵌套

  • 概述:
    函数的嵌套调用指的是 在一个函数中, 去调用另一个函数.
  • 执行流程:
    根据入栈的顺序, 进行执行的.
# 需求: 观察如下的代码, 看其执行结果是什么.
# 1. 定义 fun01 函数
def fun01():
    print('--- fun01 start ---')
    print('hello world!')
    print('--- fun01 end ---')

# 2. 定义 fun02 函数
def fun02():
    print('--- fun02 start ---')
    # 在 fun02()函数内, 调用 fun01()函数, 这就叫: 函数的嵌套调用.

    print('--- fun02 end ---')


# 3. 调用函数.
# fun01()
fun02()

案例

"""
需求: 演示函数的应用, 即: 嵌套调用.

细节:
    函数的功能越单一越好, 最好1个函数只做1件事儿.
"""

# 需求1: 定义函数, 用来打印多条横线.
# 1. 定义函数print_line(), 表示打印 1行图形.
def print_line(cols):
    """
    该函数用于打印一行的图形
    :param cols: 该行图形的 列数
    :return: 无
    """
    # 如下的循环, 是在控制 每行 打印的 列数.
    for i in range(1, cols + 1):
        print('*', end='')
    print()     # 打印完毕一行后, 记得换行.

# 2. 定义函数 print_lines(), 表示打印 多行 图形.
def print_lines(rows, cols):
    """
    该函数用于打印 多行 图形
    :param rows: 行数
    :param cols: 每行的列数
    :return: 无
    """
    # 如下的循环, 是在控制 打印的 行数
    for i in range(1, rows + 1):
        # 调用 print_line() 表示具体的打印一行.
        print_line(cols)


# # 1. 定义函数print_line(), 表示打印 1行图形.
# def print_line(cols, char):
#     # 如下的循环, 是在控制 每行 打印的 列数.
#     for i in range(1, cols + 1):
#         print(char, end='')
#     print()     # 打印完毕一行后, 记得换行.
#
# # 2. 定义函数 print_lines(), 表示打印 多行 图形.
# def print_lines(rows, cols, char):
#     # 如下的循环, 是在控制 打印的 行数
#     for i in range(1, rows + 1):
#         # 调用 print_line() 表示具体的打印一行.
#         print_line(cols, char)


# 调用函数.
# print_line(5)                    # 一次打印一行.
# print_lines(3, 5, '#')           # 3行5列
print_lines(3, 5)       # 3行5列
print('-' * 30)

print_lines(6, 8)       # 6行8列
# print_lines(6, 8, '夯')          # 6行8列
print('-' * 30)


# 需求2: 定义函数, 用于计算3个整数和, 并定义函数, 用于计算3个整数的平均值.
def get_sum(a, b, c):
    """
    该函数用于计算 3个 整数和
    :param a: 求和运算的 第一个整数
    :param b: 求和运算的 第二个整数
    :param c: 求和运算的 第三个整数
    :return: 求和结果.
    """
    return a + b + c

def get_avg(a, b, c):
    # 1. 求和.
    # sum = a + b + c         # 可以, 但是不推荐.
    sum = get_sum(a, b, c)    # 推荐使用, 调用已存在函数.
    # 2. 求平均值
    avg = sum // 3
    # 3. 返回平均值
    return avg

# 函数调用.
print(f'求和: {get_sum(10, 20, 30)}')     # 60
print(f'平均值: {get_avg(10, 20, 30)}')   # 20

函数变量作用域

  • 概述:
    变量的作用域指的是 变量的作用范围, 即: 变量在哪里能用, 在哪里不能用.
    根据变量的作用范围不同, 分为:
  • 局部变量:
      1. 定义到函数的形参列表, 或者 函数内的变量.
      1. 只能在函数内部使用, 出了函数就用不了了.
      1. 生命周期: 随着函数的调用而存在, 函数的调用完毕而消失.
  • 全局变量:
      1. 定义到函数外的变量, 或者 用 global 修饰的变量.
      1. 在当前模块中的函数, 都可以使用.
      1. 生命周期: 随着模块的加载而存在, 模块的卸载而消失.
  • global关键字介绍:
    • 作用/概述:
      被它修饰的变量 => 全局变量, 可以实现, 定义 函数内的变量, 在函数外使用.
      案例
# 需求1: 演示变量的生命周期 -> 局部变量.
def fun01():
    a = 10      # 局部变量
    print(f'函数内 a: {a}')


# 需求2: 演示变量的生命周期 -> 全局变量.
b = 30      # 全局变量
def fun02():
    global c            # 局部变量 => 全局变量
    c = 100             # 全局变量
    print(f'函数内 b: {b}')
    print(f'函数内 c: {c}')

# main函数, 程序的主入口.
if __name__ == '__main__':
    # 调用函数.
    fun01()

    # 函数外, 尝试调用 fun01()函数内的 局部变量 a
    # print(f'函数外 a: {a}')  报错, 超出了 局部变量的 生命周期.
    print('-' * 30)

    fun02()
    print(f'函数外 b: {b}')
    print(f'函数外 c: {c}')

函数参数

  • 函数参数介绍:
    • 概述:
      函数参数指的是: 形参, 实参等一些特殊的写法.
  • 分类:
    • 位置参数:
    • 关键字参数:
    • 缺省参数:
    • 不定长参数:
      *args
      **kwargs

位置参数详解:

  • 要求:
    - 实参 和 形参的 个数, 对应的顺序(位置) 都要相同.

关键字参数:

  • 要求:
    必须通过 形参名=值 的形式传递实参. 实参 和 形参的个数必须保持一致, 对顺序无要求.
  • 细节:
    如果写实参的时候, 既有: 位置参数, 又有关键字参数, 则: 位置参数 必须在 关键字参数的前边. 但是关键字参数之间是没有顺序要求的, 随便写.

位置参数和关键字参数

# 1. 定义函数, 打印信息.
def user_info(name, age, gender):  # 形参
  print(f'name: {name}, age: {age}, gender: {gender}')
# 2. 调用函数, 传递参数.
if __name__ == '__main__':
  # 位置参数 要求: 实参 和 形参 个数, 对应的顺序(位置) 都要相同.
  user_info('张三', 18, '男')  # 实参
  # user_info('张三', 18, '男', '北京')     # 报错, 实参 和 形参个数不同.
  user_info('张三', '男', 18)  # 不报错, 结果不是你要的.
  print('-' * 30)

  # 关键字参数 要求: 实参 和 形参 个数要相同, 顺序无所谓.
  user_info(age=32, gender='男', name='乔峰')
  user_info(gender='男', age=32, name='乔峰')
  print('-' * 30)

  # 细节: 如果既有位置参数, 又有关键字参数, 则: 位置参数 必须在 关键字参数的前边.
  #          位置参数            关键字参数
  user_info('段誉', gender='男', age=23)

  # 报错.  位置参数在前, 关键字参数在后.
  # user_info(gender='男', '段誉', age=23)

缺省参数

  • 概述:
    缺省参数也叫 默认参数, 它是作用于 形参列表的, 即: 可以给形参赋一个初始值, 这样用户调用函数的时候,
    如果没有给这个参数传参, 我们就用 默认值, 如果传参了, 就用给的值.
  • 细节:
    形参列表中如果有 缺省参数, 则必须放 参数列表的最后.
    先这么记忆, 不严谨, 因为如果形参既有 普通参数, 又有 缺省参数, 还有 不定长参数,
    则顺序为: 普通参数 => 缺省参数 => 不定长参数
# 1. 定义函数, user_info(), 用于打印信息.
def user_info(name, age, gender='男'):  # 缺省参数
    print(f'name: {name}, age: {age}, gender: {gender}')


# 2. 调用函数
if __name__ == '__main__':
    # 实参, 位置参数.
    user_info('张三', 30, '男')

    # 实参, 关键字参数
    user_info(name='张三', gender='男', age=30)

    # 实参, 位置参数 + 关键字参数
    user_info('阿朱', gender='女', age=25)
    print('-' * 30)

    # 测试: 缺省参数, 不传值.
    user_info('段誉', 25)
    # 测试: 缺省参数, 传值.
    user_info(age=23, name='小龙女', gender='女')

不定长参数

  • 概述:
    它是作用于 形参列表的, 主要有两种写法, 分别是
    *args: 可以接收任意多个位置参数, 并封装成: 元组.
    **kwargs: 可以接收任意多个关键字参数, 并封装成: 字典. keyword arguments
  • 细节:
      1. 不定长参数不是必须写成 *args, **kwargs, 你写成 *a, *b, *c, **a都是可以的, 但是最好做到见名知意.
      1. *args, **kwargs 是不冲突的, 可以在形参中一起使用.
# 需求1: 演示 不定长参数之  接收所有的 位置参数.
def user_info(*args):
   print(type(args))  # 
   print(args)  # ('张三', 23, '男')


# 需求2: 演示 不定长参数之  接收所有的 关键字参数.
def user_info2(**kwargs):
   print(type(kwargs))  # 
   print(kwargs)  # {'name': '李四', 'age': 24, 'gender': '女'}


# 需求3: 演示 不定长参数之  接收所有的 位置参数和 关键字参数.
def user_info3(*args, **kwargs):   # 不定长参数
   print(f'args: {args}')      # (10, 20, 30)
   print(f'kwargs: {kwargs}')  # {'name': '李四', 'age': 24, 'gender': '女'}

# 需求4: 演示 普通参数 + 缺省参数 + 不定长参数之  接收所有的 位置参数和 关键字参数.
#             普通参数      缺省参数            不定长参数
def user_info4(a, b, c=10, d=20, e='AI30期', *args, **kwargs):   # 不定长参数
   print(f'a: {a}, b: {b}, c: {c}, d: {d}, e: {e}')
   print(f'args: {args}')      # (10, 20, 30)
   print(f'kwargs: {kwargs}')  # {'name': '李四', 'age': 24, 'gender': '女'}

匿名函数

  • 概述:
    匿名函数指的是 没有名字的函数. 它类似于Java中的 lambda 表达式.
  • 格式:
    lambda 形参列表 : 函数体
  • 细节:
    匿名函数(也叫Lambda表达式, Lambda函数) 只适用于 简单的业务场景, 即: 函数体只有一行代码, 且有返回值的 这种函数.
  • 应用场景:
    匿名函数 可以作为方法的实参进行传递, 可以使得我们的代码更加简洁, 更加灵活.
# 需求1:求两个整数的和.
# 思路1:普通方式.
# def get_sum(a,b):
#     return a+b

# 需求2:自定义函数my_calculate(a,b,功能),分别计算两个整数的加减乘除.
def my_calculate(a,b,hui):
    """
    自定义函数,模拟:计算器,基于传入的功能,进而相应操作.
    :param a: 要操作的第1个整数.
    :param b: 要操作的第2个整数.
    :param func:集体的操作逻辑,即:函数对象.
    :return:计算
    """
    return hui(a,b)
# main 函数调用
if __name__ == '__main__':
    #1.测试自定义函数get_sum()
    # print(get_sum(10,3))
    # #2.函数名可以作为对象传递.
    # # sum = get_sum(10,20) #调用函数
    # func = get_sum #把函数赋值给变量func.
    # print(func(10,20))
    # #对上述代码变形,使用匿名函数.
    # my_sum = lambda a,b :a+b
    # print(my_sum(20,40))

    # 4.匿名函数作为方法的实参进行传递.
    # print(my_calculate(10,70,get_sum))
    print(my_calculate(10,30,lambda a,b:a+b))
    print(my_calculate(20,50,lambda a,b:a-b))
    print(my_calculate(50,10,lambda a,b:a*b))

总结

持续更新中~~~

你可能感兴趣的:(python,开发语言)