Python训练营打卡 Day26

@浙大疏锦行

函数专题1

知识点回顾:

  1. 函数的定义
  2. 变量作用域:局部变量和全局变量
  3. 函数的参数类型:位置参数、默认参数、不定参数
  4. 传递参数的手段:关键词参数
  5. 传递参数的顺序:同时出现三种参数类型时

1. 函数的定义:餐厅的菜单

想象你走进一家餐厅,菜单上列出了各种菜品。这些菜品就像是函数,是餐厅为你准备好的"功能"。你可以通过点菜(调用函数)来享受美食(执行功能)。

  • 函数定义:菜单上的每一道菜都有一个名字(函数名),比如"宫保鸡丁"或"红烧肉"。这些名字让你知道你可以点什么菜。

复制代码
  函数的基本写法如下所示:
  ```python

  def function_name(parameter1, parameter2, ...):
      """
      Docstring: 描述函数的功能、参数和返回值 (可选但强烈推荐)
      """
      # 函数体: 实现功能的代码
      # ...
      return value # 可选,用于返回结果
  ```

  - def: 关键字,表示开始定义一个函数。
  - function_name: 函数的名称,应遵循Python的命名约定(通常是小写字母和下划线,例如 calculate_area,用英文单词含义和下划线来作为函数名)。
  - parameter1, parameter2, ...: 函数的参数(也叫形参),是函数在被调用时接收的输入值。参数是可选的。
  - (): 参数列表必须放在圆括号中,即使没有参数,括号也不能省略。
  - : 冒号表示函数定义的头部结束,接下来是缩进的函数体。
  - Docstring (文档字符串): 位于函数定义第一行的多行字符串(通常用三引号 """Docstring goes here""")。用于解释函数的作用、参数、返回值等。可以通过 help(function_name) 或 function_name.__doc__ 查看。这个写法可选,为了后续维护和查看,建议加上这一段更加规范
  - 函数体 (Function Body): 缩进的代码块,包含实现函数功能的语句。
  - return value: return 语句用于从函数中返回一个值。如果函数没有 return 语句,或者 return 后面没有值,它会自动返回 None。一个函数可以有多个 return 语句(例如在不同的条件分支中)。
  • 调用函数:你告诉服务员你想要的菜品,比如"我要一份宫保鸡丁",这就像是在代码中调用一个函数。

    1. 不带参数的函数:固定套餐

    假设餐厅提供一种"固定套餐",你不需要告诉服务员任何额外信息,直接点这个套餐就行。

    复制代码
      def fixed_meal():
          print("这是固定套餐:宫保鸡丁 + 米饭 + 汤")
    • 比喻:你走进餐厅,直接对服务员说:"我要固定套餐。"

    • 执行:服务员知道固定套餐的内容,直接给你准备宫保鸡丁、米饭和汤。

    • 代码调用

      复制代码
      fixed_meal()  # 输出:这是固定套餐:宫保鸡丁 + 米饭 + 汤

    2. 带位置参数的函数:点具体菜品

    假设你需要点具体的菜品,比如宫保鸡丁和红烧肉,你需要按顺序告诉服务员你想要的菜品。

    复制代码
      def order_dishes(dish1, dish2):
          print(f"您点了:{dish1} 和 {dish2}")
    • 比喻:你对服务员说:"我要宫保鸡丁和红烧肉。"

    • 执行:服务员按照你点的顺序记录下来,准备这两道菜。

    • 代码调用

      复制代码
      order_dishes("宫保鸡丁", "红烧肉")  # 输出:您点了:宫保鸡丁 和 红烧肉

    3. 带默认参数的函数:点菜时有默认选项

    假设菜单上写明"宫保鸡丁默认不辣",但你可以选择修改这个默认选项。

    复制代码
      def order_dish(dish, spiciness="不辣"):
          print(f"您点了:{dish},辣度为:{spiciness}")
    • 比喻:你对服务员说:"我要宫保鸡丁。"(默认不辣)

      • 如果你有特殊要求,可以说:"我要宫保鸡丁,辣度中辣。"
    • 执行:服务员按照默认选项准备菜品,除非你有特殊要求。

    • 代码调用

      复制代码
      order_dish("宫保鸡丁")  # 输出:您点了:宫保鸡丁,辣度为:不辣
      order_dish("宫保鸡丁", "中辣")  # 输出:您点了:宫保鸡丁,辣度为:中辣

    4. 带不定参数的函数:点菜时有额外要求

    假设你可以有一些额外的要求,比如"多放点花生"或"少放点油"。

    复制代码
      def order_dish_with_extra(dish, *extras):
          print(f"您点了:{dish}")
          if extras:
              print("额外要求:", ", ".join(extras))
          else:
              print("没有额外要求")
    • 比喻:你对服务员说:"我要宫保鸡丁,多放点花生,少放点油。"

    • 执行:服务员记录下你的额外要求,并告诉厨师。

    • 代码调用

      复制代码
      order_dish_with_extra("宫保鸡丁", "多放点花生", "少放点油")
      # 输出:
      # 您点了:宫保鸡丁
      # 额外要求: 多放点花生, 少放点油

    5. 带关键词参数的函数:点菜时明确说明需求

    假设你可以通过关键词来明确你的需求,比如"辣度=中辣"或"花生=多放"。

    复制代码
      def order_dish_with_keywords(dish, **kwargs):
          print(f"您点了:{dish}")
          if kwargs:
              print("具体要求:")
              for key, value in kwargs.items():
                  print(f"  {key}: {value}")
          else:
              print("没有具体要求")
    • 比喻:你对服务员说:"我要宫保鸡丁,辣度=中辣,花生=多放。"

    • 执行:服务员清楚地记录下你的具体要求,并告诉厨师。

    • 代码调用

      复制代码
      order_dish_with_keywords("宫保鸡丁", spiciness="中辣", peanuts="多放")
      # 输出:
      # 您点了:宫保鸡丁
      # 具体要求:
      #   spiciness: 中辣
      #   peanuts: 多放

    6. 混合参数类型的函数:综合点菜

    假设你可以同时使用位置参数、默认参数、不定参数和关键词参数。

    复制代码
      def order_complete_meal(dish1, dish2="红烧肉", *extras, **kwargs):
          print(f"您点了:{dish1} 和 {dish2}")
          if extras:
              print("额外要求:", ", ".join(extras))
          if kwargs:
              print("具体要求:")
              for key, value in kwargs.items():
                  print(f"  {key}: {value}")
    • 比喻:你对服务员说:"我要宫保鸡丁,红烧肉,多放点花生,少放点油,辣度=中辣。"

    • 执行:服务员按照顺序记录你的需求,包括默认选项、额外要求和具体要求。

    • 代码调用

      复制代码
      order_complete_meal("宫保鸡丁", "红烧肉", "多放点花生", "少放点油", spiciness="中辣")
      # 输出:
      # 您点了:宫保鸡丁 和 红烧肉
      # 额外要求: 多放点花生, 少放点油
      # 具体要求:
      #   spiciness: 中辣

2. 变量作用域:厨房和餐厅的食材

假设餐厅有两个区域:厨房和餐厅。

  • 局部变量(厨房的食材):厨房里的食材(比如新鲜的鸡肉、蔬菜)只在厨房里使用,厨师用它们来准备菜品。这些食材不会出现在餐厅里,顾客也看不到它们。一旦菜品做好,这些食材就被用完了(变量被销毁)。

  • 全局变量(餐厅的食材):餐厅里有一些食材(比如调料、餐具)是所有人都可以使用的。这些食材不仅厨师可以用,服务员也可以用,甚至顾客也可以看到它们。这些食材在整个餐厅(整个程序)中都是可用的。

复制代码
  print("\n--- 变量作用域示例 ---")
  global_var = "我是一个全局变量"

  def scope_test():
      local_var = "我是一个局部变量"
      print(f"在函数内部,可以看到局部变量: '{local_var}'")
      print(f"在函数内部,也可以看到全局变量: '{global_var}'")
      # global_var = "尝试在函数内修改全局变量" # 如果没有 global 声明,这会创建一个新的局部变量 global_var
      # print(f"在函数内部,修改后的 '全局' 变量: '{global_var}'")

  scope_test()

  print(f"\n在函数外部,可以看到全局变量: '{global_var}'")
  # print(f"在函数外部,不能看到局部变量: {local_var}") # 这会产生 NameError,因为 local_var 只在函数内存在

3. 函数的参数类型:点菜的方式

当你点菜时,你可以用不同的方式告诉服务员你的需求。

  • 位置参数(按顺序点菜):你告诉服务员:"我要一份宫保鸡丁,一份红烧肉"。这里,"宫保鸡丁"和"红烧肉"是按顺序告诉服务员的,就像位置参数一样,顺序很重要。

复制代码
  # 带位置参数的函数
  def order_dishes(dish1, dish2):
      # 根据传入的位置参数执行操作
      print(f"您点了:{dish1} 和 {dish2}")

  # 调用函数时,按顺序传入参数
  order_dishes("宫保鸡丁", "红烧肉")
  # 输出:您点了:宫保鸡丁 和 红烧肉
  • 默认参数(默认的菜品选项):假设菜单上写明"宫保鸡丁默认不辣",如果你没有特别说明,厨师就会按照默认的方式(不辣)来做这道菜。如果你说"我要一份辣的宫保鸡丁",这就像是传递了一个非默认值。

复制代码
  # 带默认参数的函数
  def order_dish(dish, spiciness="不辣"):
      # 默认参数 spiciness 默认值为 "不辣"
      print(f"您点了:{dish},辣度为:{spiciness}")

  # 调用函数时,可以不传默认参数
  order_dish("宫保鸡丁")
  # 输出:您点了:宫保鸡丁,辣度为:不辣

  # 也可以传入非默认值
  order_dish("宫保鸡丁", "中辣")
  # 输出:您点了:宫保鸡丁,辣度为:中辣
  • 不定参数(额外的要求):你还可以有一些额外的要求,比如"我要一份宫保鸡丁,多放点花生"或"我要一份红烧肉,少放点油"。这些额外的要求就像是不定参数,可以有也可以没有,数量也不固定。

    复制代码
    # 带不定参数的函数
    def order_dish_with_extra(dish, *extras):
        # *extras 是一个元组,包含所有额外的要求
        print(f"您点了:{dish}")
        if extras:
            print("额外要求:", ", ".join(extras))
        else:
            print("没有额外要求")
    
    # 调用函数时,可以传入任意数量的额外要求
    order_dish_with_extra("宫保鸡丁", "多放点花生", "少放点油")
    # 输出:
    # 您点了:宫保鸡丁
    # 额外要求: 多放点花生, 少放点油
    
    # 不传额外要求
    order_dish_with_extra("宫保鸡丁")
    # 输出:
    # 您点了:宫保鸡丁
    # 没有额外要求

4. 传递参数的手段:关键词参数(点菜时说明需求)

当你点菜时,你可以明确告诉服务员你的需求,比如"我要一份宫保鸡丁,辣度是微辣,多放点花生"。这里,"辣度是微辣"和"多放点花生"就像是关键词参数,你通过参数名(辣度、花生)来明确你的需求。

复制代码
# 带关键词参数的函数
def order_dish_with_keywords(dish, **kwargs):
    # **kwargs 是一个字典,包含所有关键词参数
    print(f"您点了:{dish}")
    if kwargs:
        print("具体要求:")
        for key, value in kwargs.items():
            print(f"  {key}: {value}")
    else:
        print("没有具体要求")

# 调用函数时,通过关键词参数明确说明需求
order_dish_with_keywords("宫保鸡丁", spiciness="中辣", peanuts="多放")
# 输出:
# 您点了:宫保鸡丁
# 具体要求:
#   spiciness: 中辣
#   peanuts: 多放

# 不传关键词参数
order_dish_with_keywords("宫保鸡丁")
# 输出:
# 您点了:宫保鸡丁
# 没有具体要求

5. 传递参数的顺序:点菜的顺序

假设你点菜时可以有以下几种需求:

  1. 基本的菜品(位置参数)。

  2. 特殊的辣度要求(默认参数)。

  3. 额外的要求(不定参数)。

你必须按照这个顺序来点菜:

  1. 先告诉服务员你想要的基本菜品(位置参数)。

  2. 然后说明特殊的辣度要求(默认参数)。

  3. 最后提出额外的要求(不定参数)。

复制代码
   # 混合参数类型的函数
   def order_complete_meal(dish1, dish2="红烧肉", *extras, **kwargs):
       # dish1 是位置参数,dish2 是默认参数,*extras 是不定参数,**kwargs 是关键词参数
       print(f"您点了:{dish1} 和 {dish2}")
       if extras:
           print("额外要求:", ", ".join(extras))
       if kwargs:
           print("具体要求:")
           for key, value in kwargs.items():
               print(f"  {key}: {value}")

   # 调用函数时,同时使用位置参数、默认参数、不定参数和关键词参数
   order_complete_meal("宫保鸡丁", "红烧肉", "多放点花生", "少放点油", spiciness="中辣")
   # 输出:
   # 您点了:宫保鸡丁 和 红烧肉
   # 额外要求: 多放点花生, 少放点油
   # 具体要求:
   #   spiciness: 中辣

比如:

  • 正确的方式:"我要一份宫保鸡丁(位置参数),辣度是中辣(默认参数),多放点花生(不定参数)"。

  • 错误的方式:"我要一份宫保鸡丁,多放点花生,辣度是中辣"(顺序混乱)。

总结

通过这个"餐厅点菜"的比喻,可以更形象地理解这些编程概念:

  • 函数定义就像是菜单上的菜品,你可以通过点菜来享受服务。

  • 局部变量就像是厨房里的食材,只在厨房里使用。

  • 全局变量就像是餐厅里的调料和餐具,所有人都可以使用。

  • 位置参数就像是按顺序点菜,顺序很重要。

作业:

题目1:计算圆的面积

  • 任务: 编写一个名为 calculate_circle_area 的函数,该函数接收圆的半径 radius 作为参数,并返回圆的面积。圆的面积 = π * radius² (可以使用 math.pi 作为 π 的值)
  • 要求: 函数接收一个位置参数 radius。计算半径为5、0、-1时候的面积
  • 注意点:可以采取try-except 使函数变得更加稳健,如果传入的半径为负数,函数应该返回 0 (或者可以考虑引发一个ValueError,但为了简单起见,先返回0)。

    import math

    def calculate_circle_area(radius):
    try:
    if radius < 0:
    return 0
    return math.pi * radius ** 2
    except TypeError:
    return 0

    测试

    print(calculate_circle_area(5)) # 正常情况
    print(calculate_circle_area(0)) # 边界情况
    print(calculate_circle_area(-1)) # 负数情况
    print(calculate_circle_area("5")) # 非数字情况

题目2:计算矩形的面积

  • 任务: 编写一个名为 calculate_rectangle_area 的函数,该函数接收矩形的长度 length 和宽度 width 作为参数,并返回矩形的面积。
  • 公式: 矩形面积 = length * width
  • 要求 :函数接收两个位置参数 length 和 width。
    • 函数返回计算得到的面积。

    • 如果长度或宽度为负数,函数应该返回 0。

      def calculate_rectangle_area(length, width):
      try:
      if length < 0 or width < 0:
      return 0
      return length * width
      except TypeError:
      return 0

      测试

      print(calculate_rectangle_area(10, 5)) # 正常情况
      print(calculate_rectangle_area(-10, 5)) # 负数长度
      print(calculate_rectangle_area(10, -5)) # 负数宽度
      print(calculate_rectangle_area(-10, -5)) # 两个负数
      print(calculate_rectangle_area(10, "5")) # 非数字宽度

题目3:计算任意数量数字的平均值

  • 任务: 编写一个名为 calculate_average 的函数,该函数可以接收任意数量的数字作为参数(引入可变位置参数 (*args)),并返回它们的平均值。
  • 要求: 使用 *args 来接收所有传入的数字。
    • 如果没有任何数字传入,函数应该返回 0。

    • 函数返回计算得到的平均值。

      def calculate_average(*args):
      if not args:
      return 0
      return sum(args) / len(args)

      测试

      print(calculate_average(1, 2, 3, 4, 5)) # 正常情况
      print(calculate_average()) # 无参数
      print(calculate_average(10)) # 单个参数

题目4:打印用户信息

  • 任务: 编写一个名为 print_user_info 的函数,该函数接收一个必需的参数 user_id,以及任意数量的额外用户信息(作为关键字参数)。
  • 要求:
    • user_id 是一个必需的位置参数。

    • 使用 **kwargs 来接收额外的用户信息。

    • 函数打印出用户ID,然后逐行打印所有提供的额外信息(键和值)。

    • 函数不需要返回值

      def print_user_info(user_id, **kwargs):
      print(f"User ID: {user_id}")
      for key, value in kwargs.items():
      print(f"{key}: {value}")

      测试

      print_user_info(123, name="Alice", age=30, email="[email protected]")

题目5:格式化几何图形描述

  • 任务: 编写一个名为 describe_shape 的函数,该函数接收图形的名称 shape_name (必需),一个可选的 color (默认 "black"),以及任意数量的描述该图形尺寸的关键字参数 (例如 radius=5 对于圆,length=10, width=4 对于矩形)。
  • 要求: shape_name 是必需的位置参数。
    • color 是一个可选参数,默认值为 "black"

    • 使用 **kwargs 收集描述尺寸的参数。

    • 函数返回一个描述字符串,格式如下:

    • "A [color] [shape_name] with dimensions: [dim1_name]=[dim1_value], [dim2_name]=[dim2_value], ..."如果 **kwargs 为空,则尺寸部分为 "with no specific dimensions."

    • 复制代码
      def describe_shape(shape_name, color="black", **kwargs):
          dimensions = ", ".join([f"{key}={value}" for key, value in kwargs.items()])
          if dimensions:
              return f"A {color} {shape_name} with dimensions: {dimensions}"
          else:
              return f"A {color} {shape_name} with no specific dimensions."
      
      # 测试
      print(describe_shape("circle", radius=5))
      print(describe_shape("rectangle", color="red", length=10, width=5))
      print(describe_shape("triangle", color="blue"))
相关推荐
zm8 分钟前
服务器连接多客户端
java·javascript·算法
jllllyuz32 分钟前
matlab实现蚁群算法解决公交车路径规划问题
服务器·前端·数据库
EelBarb1 小时前
python:一个代理流量监控的媒体文件下载脚本
开发语言·python
Eric.Lee20211 小时前
python opencv 将不同shape尺寸的图片制作video视频
python·opencv·音视频
小屁孩大帅-杨一凡1 小时前
一个简单点的js的h5页面实现地铁快跑的小游戏
开发语言·前端·javascript·css·html
读心悦1 小时前
CSS 布局系统深度解析:从传统到现代的布局方案
前端·css
Amo Xiang1 小时前
Python 常用模块(八):logging模块
python·logging·日志
森哥的歌1 小时前
Python多线程
python·编程·多线程·并发·threading
椒盐螺丝钉1 小时前
CSS盒子模型:Padding与Margin的适用场景与注意事项
前端·css
抽风的雨6102 小时前
【python基础知识】Day26 函数
开发语言·python