每日反馈

老师,函数和关键字有点懵,他两有什么区别吗 函数的名称必须使用标识符的命名规则
没有意见 讲得太好啦

标识符: 程序员自己定义的具有特殊功能或含义的字符组合(可能是变量名, 可能是函数名, 可能是方法名, 可能是类名…….)
函数: 是封装一段代码或功能的容器, 在反复调用该功能时可以使用函数名称, 函数名称必须遵循标识符的命名规则

关键字: 系统定义等,或者python解释器定义的具有特殊功能或含义的字符组合

举例: 比如:gcd,是一个国家定义的具有特殊功能或含义的字符, 如果现在我成立一家公司,我起名教gcd. gcd就是关键字.
我开了一家公司,叫传智模仿学院, 这个公司名称,是我自己定义的,代表的就是我这家公司,这个名称就是标识符
现在我指定,这家公司叫传智模仿学院,我真实的这个公司,具有公司的功能和属性,同时具备赚钱的能力,那这家公司的实体,就是函数

关键字,是最高级别的定义,我们不能使用其作为我们自己功能的名称.
标识符代表了某些功能或含义,调用标识符时,其实调用的是该功能
函数是一个具体的功能,如果修改该功能的名称(标识符), 功能没有变但是调用时所使用的名称变了.

Day06知识回顾

Day07-函数 - 图1

作业讲解

  1. # 定义商品列表
  2. # product数据类型是列表,内部的每一个元素都是一个字典
  3. product_list = [
  4. {"name": "电脑", "price": 7000},
  5. {"name": "鼠标", "price": 30},
  6. {"name": "usb电动小风扇", "price": 20},
  7. {"name": "遮阳伞", "price": 50},
  8. ]
  9. # 分析一下product 的数据类型是什么??? list类型内部嵌套字典
  10. # 列表内部是每一个商品的信息组成的字典,一共有四个字典,证明有四件商品
  11. # 拥有的金钱
  12. money = 8000
  13. # 第一步: 怎样将四个商品都获取到呢?
  14. # for product in product_list:
  15. # print(product)
  16. # 第二步: 现在又一条商品信息 ,如何获取电脑的价格
  17. # computer = {"name": "电脑", "price": 7000}
  18. # print(computer['price'])
  19. # 第三步: 将获取价格的方式添加到循环中,获取每一个商品的价格
  20. # for product in product_list:
  21. # print(product['price'])
  22. #
  23. # 第四步: 将每一件商品的商品价格进行累加求和
  24. # 累加器
  25. total_price = 0
  26. for product in product_list:
  27. total_price += product['price']
  28. # 对比累加结果与拥有的金钱谁大判断是否可以购买
  29. if total_price <= money:
  30. print('可以购买')
  31. else:
  32. print('还是去搬砖吧!')

容器补充-容器间的数据类型转换[了解]

  1. # 集合, 元组, 列表间的数据类型转换 (字符串)
  2. list1 = [1, 2, 3, 3, 2, 1]
  3. tuple1 = (3, 2, 1, 1, 2, 3)
  4. set1 = {1, 2, 3, 3, 2, 1}
  5. str1 = '321123'
  6. # 1.将数据转换为列表list()
  7. # tuple和set直接将外层括号换成[]即可, 字符串需要将每个字符元素打散放入列表中
  8. print(list(tuple1)) # [3, 2, 1, 1, 2, 3]
  9. print(list(set1)) # [1, 2, 3]
  10. print(list(str1)) # ['3', '2', '1', '1', '2', '3']
  11. print('-' * 30)
  12. # 2.将数据转换为元组类型()
  13. # list和set直接将外层括号换成()即可, 字符串需要将每个字符元素打散放入元组中
  14. print(tuple(list1)) # (1, 2, 3, 3, 2, 1)
  15. print(tuple(set1)) # (1, 2, 3)
  16. print(tuple(str1)) # ('3', '2', '1', '1', '2', '3')
  17. print('-' * 30)
  18. # 3.将数据转换为set类型
  19. # 将list和tuple数据去重后放入{}内即可,str需要将每一个字符元素拆分出来,放入到集合中,并去重
  20. print(set(list1)) # {1, 2, 3}
  21. print(set(tuple1)) # {1, 2, 3}
  22. print(set(str1)) # {'1', '2', '3'}
  23. print('-' * 30)
  24. # 4.将容器数据转化哪位 str类型
  25. print(str(list1)) # [1, 2, 3, 3, 2, 1]
  26. print(str(tuple1)) # (3, 2, 1, 1, 2, 3)
  27. print(str(set1)) # {1, 2, 3}
  28. print(list1) # [1, 2, 3, 3, 2, 1]
  29. print(tuple1) # (3, 2, 1, 1, 2, 3)
  30. print(set1) # {1, 2, 3}
  31. # print函数只能打印str类型数据,控制台也只能显示str类型数据
  32. # 每次打印数据时,都先将数据类型转换为str再打印,所以我们转换不转换在底层都会帮我们执行一次转换工作
  33. # 将数据转换为str类型后就是打印出来的数据形式.
  34. # 预告: 当我们学习面向对象后, 就能够证明这个结论了,先记住就可以了

练习: list1 = [1,2,3,3,2,1] 使用容器间的数据类型转换将其去重后,转换为tuple类型

  1. list1 = [1, 2, 3, 3, 2, 1]
  2. # 将list 转换为set类型数据,实现去重
  3. set1 = set(list1)
  4. # 去重后再将set1转换为tuple类型
  5. tuple1 = tuple(set1)

00-今日知识内容

  1. 函数的说明文档
  2. 函数的参数
  3. 函数的返回值
  4. 函数的作用域
  5. 函数的嵌套
  6. 函数的执行流程
  7. 函数的进阶
    1. 参数详解

      01-函数的说明文档[掌握]

      ```python

      自定义一个函数,在函数内部计算1-100的累加和,并打印结果

import requests

def sum_func(): ‘’’计算1-100的累加和 尽量使用三对双引号进行文档注释,否则会报灰色波浪线’’’

  1. # 灰色波浪想,说明不符合语法规范
  2. sum1 = 0
  3. for i in range(1, 101):
  4. sum1 += i
  5. print(f'1-100的累加和是{sum1}')

调用函数时,如果只看函数名称,不能知道函数具体在做什么.

如果想要知道函数具体是做什么的,我们可以在函数定义的位置进行注释

但是如果定义位置和调用位置,间隔很远或在其他文件中调用该函数,则无法准确找到注释位置

sum_func() # 1-100的累加和是5050

函数的说明文档: 可以在提示信息中展示出来的说民文字

提示信息出现的方式,鼠标悬停在函数调用位置上方,或者按住ctrl鼠标悬停

格式: 在函数体的第一行书写多行注释,则为说明文档

def func1(): “””打印一首诗””” print(‘蓬头小儿学垂纶,侧坐莓苔草映身’)

func1()

**说明文档的出现位置**<br />![image.png](https://cdn.nlark.com/yuque/0/2022/png/1280980/1657248058571-7ff101b4-b7f3-44f8-8658-4eddcae79155.png#clientId=ude265de0-5a68-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=247&id=u3c992008&margin=%5Bobject%20Object%5D&name=image.png&originHeight=371&originWidth=1104&originalType=binary&ratio=1&rotation=0&showTitle=false&size=54182&status=done&style=none&taskId=uef79219e-38d9-4d7d-8112-49645f467ed&title=&width=736)
<a name="IwyS7"></a>
# 02-函数参数的简单使用[掌握]
```python
# 函数的参数,就是从函数的外部传递数据给函数的内部,用于运算或执行的一种工具
# 函数的参数,让函数变得更加灵活,复用率更高

# 举例: print函数,传入不同的数据,就打印不同的内容.通过控制参数的内容,控制执行行结果

# 需求1: 定义一个函数,计算3+4和和
def func1():
    print(3 + 4)


func1()  # 7


# 需求2: 定义一个函数,计算5+6的和
def func2():
    print(5 + 6)


func2()  # 11


# 需求3: 我们要定义一个加法计算器,可以计算任意两个数字相加的和
# 如果没有参数,我们要定义无数个函数
# 函数参数的使用格式:  def 函数名(参数1, 参数2.....)

# def func3(参数1, 参数2):
#     参数参与运算

def func3(num1, num2):
    print(num1 + num2)


func3(5, 6)
func3(3, 4)

# 名词解释:
# 在函数定义时,使用的参数,叫做形参(形式上的参数), 该参数负责占位,接收到外接传递进来的数据时,使用该数据参与函数内部的运算或执行
# 在函数调用时,使用的参数,叫做实参(实际参与运算或执行的参数),该参数的值会传递给形参.


# 调用时,要注意,有多少个参数,调用时就需要进行多少个参数的传智,必须保证每一参数有值,否则报错
# TypeError: func3() missing 1 required positional argument: 'num2'
# func3(2)
# TypeError: func3() takes 2 positional arguments but 3 were given
# func3(2,3,4)

image.png

03-函数的返回值[掌握]

如果我们从函数体内部获取到数据,不使用print打印 ,则无法在控制台显示.

# 函数的返回值就是我们函数内部代码运算或者执行后得到的结果传递到函数外部的一种工具
# 返回值的使用方式: 在函数的末尾 使用return结束函数并返回数据


# def func1(num1, num2):
#     print(num1 + num2)


# 如果我想在函数体外获取我们的计算结果,并且进行*2的操作我该怎么做???
# result = func1(3, 4)

# print(result)  # None  使用变量接收运行结果,由于我们没有书写返回值,则默认返回了None


# 上述函数中计算的结果,我们在函数体外获取不到

# 如果想在函数体外获取到函数体内运行的结果,则需要借助返回值来完成

def func2(num1, num2):
    # 使用return将两个数字相加的结果进行返回
    return num1 + num2


# 此时可以使用变量接收num1+num2的和
result = func2(3, 4)
# 我们虽然获取了函数体内部传递出来的数据,但是如果不适用print我们没有办法看到控制台上的数据,此时数据在内存中
print(result*2)

练习:
计算1-n的累加和 n用参数传递进去,得到的结果再函数体外做减法操作, -11, 将计算结果打印出来

# 计算1-n的累加和  n用参数传递进去,得到的结果再函数体外做减法操作, -11, 将计算结果打印出来

# 第一步: 计算1-10的累加和
sum1 = 0
for i in range(1, 11):
    sum1 += i

print(sum1)


# 第二步: 将计算1-10 的累加和放入函数中
def func1():
    sum1 = 0
    for i in range(1, 11):
        sum1 += i

    print(sum1)


func1()


# 第三步:增加参数,动态调整计算的范围
def func1(num):
    sum1 = 0
    for i in range(1, num + 1):
        sum1 += i

    print(sum1)


func1(5)

# 第四步: 增加返回值,在函数体外-11
def func1(num):
    sum1 = 0
    for i in range(1, num + 1):
        sum1 += i

    return sum1


print((func1(100) - 11))

04-函数的作用域[熟悉]

# 思考: 为什么我们要使用 return进行获取sum1呢?  我们可不可以在函数体外直接调用sum1呢?
def func1(num):
    sum1 = 0
    for i in range(1, num + 1):
        sum1 += i

    return sum1


print((func1(100) - 11))
# NameError: name 'sum1' is not defined
# 报错,sum1没有被定义,结论: 在函数体内定义的变量,在函数体外不能使用
# print(sum1 - 11)

# 变量具有作用域: 数据生效的范围
# 全局变量:在文件在中顶格书写,可以在函数内核函数外使用的变量
# 局部变量: 在函数体内定义的,只能在定义该变量的函数体内使用的变量,例如我们刚才使用的sum1

# 全局变量,此时该变量,在函数体内,和函数体外均可以被调用
age = 18

# 在函数体外使用age变量
print(f'小明的年龄是{age}')

# 在函数体内使用age变量
def func1():
    print(f'小明的年龄是{age}')

func1()

# 局部变量
# 只能在定义该变量的函数体内使用

# 定义一个函数,在函数体内定义一个变量
# 在定义name变量的函数体内可以使用该变量
def func2():
    name = '小明'
    print(f'我的名字叫做{name}')

func2()

# 在函数体外无法使用name变量
# NameError: name 'name' is not defined
# print(name)

# def func3():
#     # 在其他函数的函数体内,也不能使用name变量
#     # NameError: name 'name' is not defined
#     print(f'我的名字叫做{name}')
#
# func3()


# 如果现在有一个局部变量和一个全局变量,变量名称相同,此时是否能够定义成功,成功定义后,优先使用全局还是局部呢?
def func3():
    # 20 优先使用局部变量,此处没有修改全局变量的值,而是创建了一个新的局部变量,出了函数体,该局部变量消失
    age = 20
    print(age)

func3()

print(age) # 18  函数体外调用的是全局变量

# 注意:在开发中,我们尽量避免局部变量和全局变量同名

05-global关键字[掌握]

一般需要在函数体内修改全局变量时, 我们先使用global关键字声明其使用的是全局变量

# global关键字,就是声明当前我们使用的变量是全局变量
# 一般需要在函数体内修改全局变量时, 我们先使用global关键字声明其使用的是全局变量

# 定义一个全局变量
num = 10


# 定义一个函数
def func():
    print(num)


func()  # 10 如果仅仅使用全局变量,不需要声明,没有同名局部变量,会自动去全局变量中查找


def func2():
    num = 5
    print(num)


func2()  # 此处num=5是创建了一个新的局部变量

print(num)  # 此处全局变量num的值依然没有变化


# 修改全局变量的值
def func3():
    # 想要在函数体内修改全局变量,先要声明自己使用的就是全局变量
    global num
    num = 9

# 使用global声明后,就可以正常修改全局变量了
func3()
print(num)  # 9


# 思考:这种方式会不会让num自增呢?
def func4():
    # UnboundLocalError: local variable 'num' referenced before assignment
    # num += 1 >>> num = num + 1 >>> num = ?
    # 当num = ? 是在进行局部比那辆的定义
    # 当我们先进行num + 1计算时,我们查找到局部变量中有num 但是该num还没有定义完成,所以就报错
    # 所以使用复合赋值运算符计算全局变量时,需要先使用global进行声明
    global num
    num += 1

func4()
print(num)

# def func5():
#     # 先打印一个局部变量的值
#     num = 11
#     print(num)
#     # 再打印一个全局变量的值
#     # SyntaxError: name 'num' is used prior to global declaration
#     # global声明必须写在所有的被声明变量之前
#     # 一个函数内同样的标识符只有一个含义,num不能既代表局部变量,又代表全局变量
#     global num
#     print(num)

# 总结:
# 1. 如果我们想在函数体内修改全局变量的值,则需要在函数体中使用global声明我们使用的是全局变量
# 2. 当我们仅仅使用全局变量时,不需要声明
# 3.当我们使用global修改了全局变量后,该修改在全局范围内生效
# 4.全局变量和局部变量同名可以理解为两个变量只不过名称相同,但是在同一个位置,该变量名称只能代表一个数据

注意: 无论是循环结构内,还是分支结构内,只要我们的变量不是在函数体内定义的就是全局变量,在函数体内定义就是局部变量.

06-函数的嵌套使用[熟悉]

# 函数的嵌套: 这里特指函数定义的内部嵌套函数的调用

# 其实这个我们在之前已经使用过很多次了,例如,我们在函数定义内部调用print函数

# 下面我们在自定义的函数内部调用一次自定义的函数

def func1():
    """函数执行某个功能"""
    print('功能开始')
    print('hello world')
    print('功能结束')


def func2():
    """在func2中调用func1"""
    print('程序开始')
    func1()
    print('程序结束')


func2()


# 执行过程描述: 调用func2,执行代码块,当执行到func1的调用位置,将func1函数体内代码全部执行完成后继续向后执行func2中的命令

# 案例:
# 创建两个函数: 第一个函数就是打印一行横线,第二个函数,就是根据传入的n的值打印多条横线,在第二个函数中,调用第一个函数

def print_line():
    """打印一行横线"""
    print('-' * 30)

def print_lines(n):
    """根据n的值,打印多条横线"""
    for i in range(n):
        print_line()

print_lines(5)

练习: 创建两个函数:第一个函数,就是计算三个数字的和, 第二个函数时计算三个数字的平均数, 在第二个函数中调用第一个函数求和,并除以3求平均值.
答案见下一小节代码

07-函数返回值和参数的传递流程[掌握]

# 练习: 创建两个函数:第一个函数,就是计算三个数字的和,  第二个函数时计算三个数字的平均数,  在第二个函数中调用第一个函数求和,并除以3求平均值.

def sum_three(num1, num2, num3):
    """求三个数字的和"""
    return num1 + num2 + num3


def average_three(a, b, c):
    """求三个数字的平均值,调用sum_three"""
    return sum_three(a, b, c) / 3


# 调用求平均值的函数
print(average_three(3, 4, 5))  # 4.0

# 结论: 参数从外层函数向内层函数调用那位置进行传递,返回值从内层一层一层传递出来

参数从外向内一层一层传递
image.png
函数的返回值从内向外逐层传递
image.png

08-函数的执行流程[熟悉]

# 练习: 创建两个函数:第一个函数,就是计算三个数字的和,  第二个函数时计算三个数字的平均数,  在第二个函数中调用第一个函数求和,并除以3求平均值.

# 思考1:函数1, 和函数2定义位置能否互换
# def sum_three(num1, num2, num3):
#     """求三个数字的和"""
#     return num1 + num2 + num3


def average_three(a, b, c):
    """求三个数字的平均值,调用sum_three"""
    return sum_three(a, b, c) / 3


def sum_three(num1, num2, num3):
    """求三个数字的和"""
    return num1 + num2 + num3


# 调用求平均值的函数
print(average_three(3, 4, 5))  # 4.0

# 1.函数的执行顺序,是咋程序启动后,先记录函数的函数名称,保存在内存中,不会执行函数体内的代码直到被调用
# 2.当我么你调用函数时,系统会去刚才记录函数名称的位置查找函数,如果函数存在,则调用函数体中的代码,如果不存在,则报错
# 3.系统内置函数时怎么加载进来的呢? Python启动的时候,已经将Python的核心库加载到内存中了,可以随意使用
# 4.再执行函数前,该函数被定义了即可,函数定义间的先后顺序不重要

image.png

09-函数返回值加强[熟练使用]

# 1.return作用: 1. 向函数体外部返回数据  2.结束函数的运行
# 所以.在一个函数体内,只能有一个return被执行

def func():
    print('hello python')
    return
    return
    # 在一个函数体中 return执行后函数终止了,所以return之后的所有代码将不会继续执行.
    print('hello bigdata')


func()  # hello python

# 执行到return之后,函数结束了,但是代码可以 继续执行
print('函数执行结束')


# 2.使用return返回数据时,入果写值,则返回该值,如果不写值,则默认返回None,如果不写return同样返回None
def func1():
    return


# return之后不写任何内容,默认返回None
print(func1())  # None


def func2():
    print('hello world!!!')
    if True:
        print('abc')


# 如果再函数体内,不书写return,则默认返回None
print(func2())  # None


# 回忆: 为什么list中的方法append 打印或得到None,  因为该方法没有返回值.
# 之前我们的解释是没有新的数据容器产生.(这种解释的意思就是没有返回值)

# 思考: 哪些方法或函数可以用变量接收?  有明确返回值的可以用变量接受, 如果没有或者返回值为None,则不需要接收.
# 当我们获取返回值后,如果直接让返回值参与运算或执行,则只能使用一次,如果使用变量保存返回值,则可以重复使用.

# 3.返回值有且只能有一个
def func3():
    return 1, 2, 3

# 如果我们返回多个数据,并且用逗号隔开,则会自动打包为一个元组并进行返回
print(func3()) # (1, 2, 3)
# 如果我们不返回数据,则默认返回一个None

# 4.如果手动返回数据,必须书写return,目前Python没有提供除了return之外的任何返回方式

10-参数加强-实参-位置参数[熟练使用]

# 实参我们之前使用的都是位置参数,就是根据形参位置,从左至右依次赋值的形式.数量不能多也不能少,必须保证每一个形参有值

def func(a, b, c, d):
    print(a, b, c, d)


# 实参部分使用位置参数进行传参
func(1, 2, 3, 4)
# 1. 传参数量不能多也不能少
# TypeError: func() missing 1 required positional argument: 'd'
# func(1, 2, 3)
# TypeError: func() takes 4 positional arguments but 5 were given
# func(1, 2, 3, 4, 5)

# 2. 位置参数只能按序赋值,不能跳跃或者指定位置赋值.

11-参数加强-实参-关键字参数[熟练使用]

# 关键字参数赋值,就是根据形参名称对于指定的形参进行赋值的方式
# 赋值格式: 形参名 = 值
# 其实以前也一直在使用, print('', end=' ')  sort(reverse=True)

def func1(a, b, c, d):
    print(a, b, c, d)


# 使用关键字参数对于func进行赋值调用
func1(a=1, b=2, c=3, d=4)

# 如果更换abcd的顺序,会不会报错呢??? 不会报错
func1(d=4, c=3, b=2, a=1)

# 可以使用关键字参数和位置参数混合赋值么? 可以
func1(1, 2, c=3, d=4)

# 注意:
# 1.关键字参数赋值不能重复赋值,也不能遗漏赋值
# TypeError: func1() got multiple values for argument 'a'
# 位置参数赋值,将a赋值为1, 关键字参数又给1赋值了一次,重复赋值会报错
# func1(1,2,c=3,a=1)

# 不能遗漏赋值
# TypeError: func1() missing 2 required positional arguments: 'c' and 'd'
# func1(a=1, b=2)

# 2.赋值的形参名称必须存在
# TypeError: func1() got an unexpected keyword argument 'e'
# 关键字参数赋值,对于e进行了赋值,但是没有对应的形参接收,所以报错
# func1(a=1, b=2, c=3, d=4, e=5

12-参数加强-形参-位置参数[熟练使用]

# 形参中的位置参数就是从左只有依次定义的,这种参数必须赋值,未赋值就会报错
def func(a, b, c):
    print(a, b, c)


func(1, 2, 3)

# 位置参数可以使用位置参数赋值和关键字参数赋值的形式,赋值时不能遗漏即可

13-参数加强-形参-缺省错参数[熟练使用]

# 缺省参数:又叫做默认参数,可以理解为,在定义形参时,给其一个默认值,如果我们不赋值,就使用默认值,如果我们赋值,就是用新赋予的值
# 格式: 形参名=值
# 缺省参数,是形参中的参数,定义函数是,只能放在位置参数之后
def func1(a, b, c=10):
    print(a, b, c)


# 当给缺省参数赋值时,该参数就使用新值
func1(1, 2, 3)  # 1 2 3
# 当不给缺省参数赋值时,该参数就使用默认值
func1(1, 2)  # 1 2 10


# 如果缺省参数写在位置参数之前就会报错
# SyntaxError: non-default argument follows default argument
# 缺省参数在函数定义时,只能写在位置参数之后.
# def func2(c=10, a, b):
#     print(a, b, c)


# 注意: 一般缺省参数中设置的默认值是不需要修改的,极少数情况下我们会自己添加
# 例如: def print(self, *args, sep=' ', end='\n', file=None):
# print间隔符是空格,结束符是换行,一般情况下我们不修改,极少情况下我们需要修改,所以使用缺省参数

# 举例: 如果我们写一个函数记录班级每个学员的个人信息,有如下几个参数哪一适合作为缺省参数出现:
# 1.身高, 2.性别 3. 国籍  一般国籍可以作为缺省参数,因为绝大部分同学都是中国国籍

14-参数加强-形参-位置不定长参数[了解]

# 位置不定长参数:*args代表
# 作用: 可以获取任意多个位置参数 (0个或多个)
# 格式: *args

# 1. 使用位置参数给args进行赋值,可以赋值任意多个,会将传入的值打包为一个元组,保存在args当中.
# 需求:定义一个函数,求任意多个数值的平均值.
def avg(*args):
    print(args)  # (1, 2, 3, 4, 5, 5)
    return sum(args) / len(args)


print(avg(1, 2, 3, 4, 5, 5))  # 3.3333333333333335


# 2.args不能使用关键字参数赋值
# TypeError: avg() got an unexpected keyword argument 'args'
# avg(args=(1, 2, 3, 4, 5))
# SyntaxError: invalid syntax
# avg(*args = (1, 2, 3, 4))

# 3.args只是一个形参名称,可以修改为任意标识符,但是修改成什么在函数体内就用什么.
# 辨别是否为不定长参数的依据是* 而不是变量名称
def avg(*nums):
    print(nums)  # (1, 2, 3, 4, 5, 5)
    return sum(nums) / len(nums)


print(avg(1, 2, 3, 4, 5, 5))  # 3.3333333333333335


# 4.位置不定长参数可以和其他参数一起使用,建议藏在位置参数之后,缺省参数之前
def func3(a, b, *args, c=10):
    print(a)
    print(b)
    print(c)
    print(args)


# 此时, 按照先后顺序进行赋值,此时永远不会给缺省参数赋值,缺省参数建议使用关键字参数赋值的形式修改.
func3(1, 2, 3, 4, 5, 5, 6, 7, 7, 8, 8)


# 如果缺省参数在*args之前则每次给args赋值,都必须修改缺省参数的值
def func3(a, b, c=10, *args):
    print(a)
    print(b)
    print(c)
    print(args)

# 按照先后顺序赋值,如果args想要有值,必须修改缺省参数的值,所以这种方式不推荐
func3(1, 2, 3, 4, 5, 5, 6, 7, 7, 8, 8)

# 总结: 形参的顺序是 位置参数 >>> 位置不定长参数 >>> 缺省参数
# 有官方依据: def print(self, *args, sep=' ', end='\n', file=None)

练习: 定义一个函数,使用位置不定长参数进行接收,计算任意多个数字的和, 同时输出1-这个和的累加和
举例: 在函数中添加实参1,2,3 最终的到的结果是 1-6的累加和

# 练习: 定义一个函数,使用位置不定长参数进行接收,计算任意多个数字的和, 同时输出1-这个和的累加和
# 举例: 在函数中添加实参1,2,3   最终的到的结果是 1-6的累加和

def func(*args):
    # 1. 计算任意多个数字的和
    sum_nums = sum(args)
    print(sum_nums)

    # 2.计算1-sum_nums的累加和
    # 方式一:
    # 创建累加器
    sum1 = 0
    for i in range(1, sum_nums + 1):
        sum1 += i
    # 方式二:
    # sum1 = sum(range(1, sum_nums + 1))

    print(f'1-{sum_nums}的累加和是{sum1}')


func(1, 2, 4, 5, 3, 2, 1)

函数嵌套形式

# 练习: 定义一个函数,使用位置不定长参数进行接收,计算任意多个数字的和, 同时输出1-这个和的累加和
# 举例: 在函数中添加实参1,2,3   最终的到的结果是 1-6的累加和

def func(*args):
    # 1. 计算任意多个数字的和
    sum_nums = func1(args)

    # 2.计算1-sum_nums的累加和
    # 方式一:
    # 创建累加器
    func2(sum_nums)

def func1(args):
    sum_nums = sum(args)
    return sum_nums


def func2(sum_nums):
    sum1 = 0
    for i in range(1, sum_nums + 1):
        sum1 += i
    # 方式二:
    # sum1 = sum(range(1, sum_nums + 1))

    print(f'1-{sum_nums}的累加和是{sum1}')

func(1, 2, 4, 5, 3, 2, 1)

15-形参加强-形参-关键字不定长参数[了解]

# 关键字不定长参数:接收任意多个关键字参数的形参类型

# 格式: **kwargs

# 1.使用关键字参数对于关键字不定长参数赋值,会将没有参数接收的关键字参数接收,接收后将关键字参数转化字典保存在kwargs形参中
def func1(**kwargs):
    print(kwargs)  # {'a': 1, 'b': 2, 'c': 3}


# TypeError: func1() takes 0 positional arguments but 3 were given
# 现在又0个位置参数,但是你给了他3个值
# 可以说明我们使用位置参数,并不能给kwargs赋值
# func1(1, 2, 3)

# 使用关键字参数赋值
func1(a=1, b=2, c=3)


def func2(a, b, **kwargs):
    print(kwargs)  # {'c': 3}


# 在形参中有a和b参数,则ab的值被形参接收,没有c 所以kwargs接收了c
func2(a=1, b=2, c=3)


# 2.kwargs也只是一个参数名称,可以随意修改,但是我们很一般不修改
def func3(**chaunzhi):
    print(chaunzhi)  # {'a': 1, 'b': 2, 'c': 3}


func3(a=1, b=2, c=3)


# 3.关键字不定长参数可以和其他参数类型一起使用,但是必须放在参数列表的末尾
def func4(a, b, *args, c=10, **kwargs):
    print(a)
    print(b)
    print(c)
    print(args)
    print(kwargs)


func4(1, 2, 3, 4, 5, 6, 7, c=12, d=1, e=2)


# 注意:
# 1.位置不定长参数和关键字不定长参数,在一个函数中分别只能出现一次
# def func5(*args, *chuanzhi):  这样是不可以的

# 2.如果一个函数中有*args 和**kwargs则可以接收一切参数

# 3.如果参数数量多或者参数类型多我们会使用文档注释(文档说明)(详细版)
# 在函数体的第一行输入三对引号,点击回车即可出现参数和返回值提示
def func5(a, b, *args, c=10, **kwargs):
    """
    函数作用: 验证所有的参数类型
    :param a: 第一个位置参数
    :param b: 第二个位置参数
    :param args: 位置不定长参数
    :param c: 缺省参数
    :param kwargs: 关键字不定长参数
    :return: 返回值为None
    """
    print(a)
    print(b)
    print(c)
    print(args)
    print(kwargs)


func5(1, 2, 3, 4, 5, 6, 7, c=12, d=1, e=2)

image.png

作业

07-函数作业.md
07-函数答案.md

作业提交

点击查看【jinshuju】

文件链接

百度云盘: 链接:https://pan.baidu.com/s/13TqhouBQ8h1lP2VFtQHgMw 提取码:lh3d
阿里云盘:「python+大数据79期基础」等文件 https://www.aliyundrive.com/s/G6iPqGFQgfJ