当前位置:首页>python>【Python】Day16:函数进阶与变量作用域

【Python】Day16:函数进阶与变量作用域

  • 2026-10-11 07:35:22
【Python】Day16:函数进阶与变量作用域

🎯 学习目标

  1. 掌握 默认参数:让参数有默认值,调用时可以省略
  2. 掌握 可变参数:*args 和 **kwargs,应对不确定数量的参数
  3. 深入理解 变量作用域:局部变量 vs 全局变量
  4. 学会使用global关键字在函数内修改全局变量
  5. 能编写更灵活、更健壮的函数

一、默认参数

  1. 基本用法
    defgreet(name, city="北京"):    print(f"我叫{name},来自{city}")greet("小王")              # 我叫小王,来自北京(city用默认值)greet("小李", "上海")      # 我叫小李,来自上海(city用传入值)
  2. 默认参数必须放在非默认参数后面
    # ❌ 错误# def greet(city="北京", name):#     pass# SyntaxError: non-default argument follows default argument# ✅ 正确defgreet(name, city="北京"):pass

二、可变参数

  1. *args:接收任意数量的位置参数(打包成元组)
    defget_sum(*args):    print(args)          # (1, 2, 3, 4)    print(type(args))    # <class 'tuple'>return sum(args)print(get_sum(1, 2, 3, 4))    # 10print(get_sum(10, 20))        # 30
  2. **kwargs:接收任意数量的关键字参数(打包成字典)
    defprint_info(**kwargs):    print(kwargs)        # {'name': '小王', 'age': 18}    print(type(kwargs))  # <class 'dict'>for key, value in kwargs.items():        print(f"{key}: {value}")print_info(name="小王", age=18)
  3. 参数顺序规则
    deffunc(位置参数, *args, 关键字参数, **kwargs):pass# 完整示例defstudent_info(id, *courses, city="北京", **details):    print(f"学号:{id}")    print(f"选课:{courses}")    print(f"城市:{city}")    print(f"详情:{details}")student_info("S001", "数学", "英语", city="上海", age=18, gender="男")# 学号:S001# 选课:('数学', '英语')# 城市:上海# 详情:{'age': 18, 'gender': '男'}

三、变量作用域

  1. 局部变量:函数内部定义的,外部访问不到

    deftest():    x = 10# 局部变量    print(x)test()           # 10# print(x)       # NameError: name 'x' is not defined
  2. 全局变量:函数外部定义的,所有地方都能访问

    message = "Hello"# 全局变量deftest():    print(message)  # 可以访问test()              # Helloprint(message)      # Hello
  3. 函数内"修改"全局变量:必须用global

    count = 0defincrement():global count      # 声明 count 是全局变量    count += 1increment()print(count)         # 1# 不用 global 会怎样?count = 0defincrement_bad():# count += 1     # UnboundLocalError: 局部变量在赋值前被引用pass
  4. LEGB 规则(了解)Python 查找变量的顺序:Local → Enclosing → Global → Built-in

    x = "global"defouter():    x = "enclosing"definner():        x = "local"        print(x)      # local(优先用最近的)    inner()outer()

四、函数作为参数传递(初识)

  1. 函数是一等公民:可以当参数传
    defadd(a, b):return a + bdefcalculate(a, b, func):return func(a, b)print(calculate(3, 5, add))    # 8

⚠️ 常见坑

  1. 默认参数使用可变对象(经典坑!)
    # ❌ 错误:默认列表只创建一次,会累积!defappend_item(item, lst=[]):    lst.append(item)return lstprint(append_item("a"))   # ['a']print(append_item("b"))   # ['a', 'b']  诡异!# ✅ 正确:用 None 代替defappend_item(item, lst=None):if lst isNone:        lst = []    lst.append(item)return lst
  2. 忘记global就修改全局变量
    total = 0defadd_score(s):# total += s   # UnboundLocalError!global total    total += s

✍️ 实战练习

  1. 灵活的成绩计算器
    • 要求:用*args接收任意数量的成绩,返回平均分和最高分。
    • 示例:
      defscore_stats(*scores):ifnot scores:return0, 0return sum(scores) / len(scores), max(scores)avg, highest = score_stats(85, 90, 78, 92)print(f"平均分:{avg},最高分:{highest}")
  2. 全局计数器
    • 要求:用全局变量记录函数被调用了多少次。
    • 示例:
      call_count = 0defmy_function():global call_count    call_count += 1    print(f"这是第{call_count}次调用")my_function()  # 这是第1次调用my_function()  # 这是第2次调用

✅ 自测清单

  • [ ] 能使用默认参数,知道默认参数必须放在最后
  • [ ] 知道默认参数不要用可变对象(如[]),应该用None
  • [ ] 能用*args接收任意数量的位置参数(变成元组)
  • [ ] 能用**kwargs接收任意数量的关键字参数(变成字典)
  • [ ] 能区分局部变量和全局变量
  • [ ] 知道在函数内修改全局变量必须用global声明

最新文章

随机文章