Python函数:作用域(局部变量和全局变量)③

在这里插入图片描述

前言

在Python编程中,理解变量的作用域是至关重要的。变量的作用域决定了变量的可访问性和生命周期。本文将深入探讨Python中局部变量和全局变量的概念、它们的区别、使用场景以及在函数中如何正确使用这两类变量。为了更好地理解这些概念,我们将提供详细的解释和代码示例,并在最后附上一个综合详细的例子。

1. 什么是作用域?

作用域(scope)指的是变量在代码中的可见范围。Python中有四种作用域:

  1. 局部作用域(Local Scope):函数内部定义的变量,其作用范围仅限于函数内部。
  2. 封闭作用域(Enclosing Scope):嵌套函数中的变量,其作用范围仅限于外层函数及其内部。
  3. 全局作用域(Global Scope):模块级别定义的变量,其作用范围是整个模块。
  4. 内置作用域(Built-in Scope):Python内置的名字空间,包括所有的内置函数和异常等。

本文重点讨论局部作用域和全局作用域。

2. 局部变量

局部变量是指在函数内部定义的变量,它们只能在函数内部访问和使用。当函数执行完毕后,局部变量会被销毁。

局部变量示例
def my_function():
    local_var = 10  # 局部变量
    print(f"函数内部,local_var 的值是: {local_var}")

my_function()
# print(local_var)  # 这行代码会报错,因为 local_var 是局部变量,在函数外部不可访问

在上述代码中,local_var 是一个局部变量,它只能在 my_function 函数内部访问。试图在函数外部访问 local_var 会导致错误。

3. 全局变量

全局变量是指在函数外部定义的变量,它们可以在整个模块中访问和使用。全局变量的作用范围是整个程序,除非明确地在函数内部重新定义。

全局变量示例
global_var = 20  # 全局变量

def my_function():
    print(f"函数内部,global_var 的值是: {global_var}")

my_function()
print(f"函数外部,global_var 的值是: {global_var}")

在上述代码中,global_var 是一个全局变量,它可以在 my_function 函数内部和外部访问。

4. 局部变量与全局变量的区别

  1. 定义位置

    • 局部变量:定义在函数内部。
    • 全局变量:定义在函数外部。
  2. 作用范围

    • 局部变量:只能在定义它们的函数内部访问。
    • 全局变量:可以在整个模块中访问。
  3. 生命周期

    • 局部变量:函数执行完毕后,局部变量会被销毁。
    • 全局变量:程序执行完毕前,全局变量一直存在。

5. 在函数中使用全局变量

尽管在函数中可以直接读取全局变量,但如果要在函数中修改全局变量的值,需要使用 global 关键字。

修改全局变量示例
counter = 0  # 全局变量

def increment_counter():
    global counter  # 声明使用全局变量
    counter += 1
    print(f"函数内部,counter 的值是: {counter}")

increment_counter()
print(f"函数外部,counter 的值是: {counter}")

在上述代码中,我们使用 global 关键字声明 counter 变量为全局变量,以便在函数 increment_counter 中对其进行修改。

6. 嵌套函数中的变量作用域

在Python中,可以在一个函数内部定义另一个函数,这种情况下内部函数可以访问外部函数的变量,这些变量属于封闭作用域。

嵌套函数示例
def outer_function():
    outer_var = "外部变量"

    def inner_function():
        print(f"内部函数访问外部变量: {outer_var}")

    inner_function()

outer_function()

在上述代码中,内部函数 inner_function 可以访问外部函数 outer_function 中的变量 outer_var

7. 使用 nonlocal 关键字

在嵌套函数中,如果需要修改外部函数的变量,可以使用 nonlocal 关键字。

nonlocal 示例
def outer_function():
    outer_var = 10

    def inner_function():
        nonlocal outer_var  # 声明使用外部函数的变量
        outer_var += 5
        print(f"内部函数中,outer_var 的值是: {outer_var}")

    inner_function()
    print(f"外部函数中,outer_var 的值是: {outer_var}")

outer_function()

在上述代码中,我们使用 nonlocal 关键字声明 outer_var 变量为外部函数的变量,以便在内部函数 inner_function 中对其进行修改。

8. 综合详细的例子

下面是一个综合详细的例子,展示了局部变量、全局变量、嵌套函数中的变量作用域以及 globalnonlocal 关键字的使用。

import datetime

# 全局变量
tasks_completed = 0

class Task:
    def __init__(self, title, description, due_date):
        self.title = title
        self.description = description
        self.due_date = due_date
        self.completed = False

    def mark_completed(self):
        global tasks_completed  # 使用全局变量
        self.completed = True
        tasks_completed += 1

    def __str__(self):
        status = "已完成" if self.completed else "待完成"
        return f"任务: {self.title}, 状态: {status}, 截止日期: {self.due_date}"

class TaskManager:
    def __init__(self):
        self.tasks = []

    def add_task(self, title, description, due_date):
        task = Task(title, description, due_date)
        self.tasks.append(task)

    def remove_task(self, title):
        self.tasks = [task for task in self.tasks if task.title != title]

    def get_pending_tasks(self):
        return [task for task in self.tasks if not task.completed]

    def get_completed_tasks(self):
        return [task for task in self.tasks if task.completed]

    def get_overdue_tasks(self):
        today = datetime.date.today()
        return [task for task in self.tasks if task.due_date < today and not task.completed]

    def summary(self):
        pending_tasks = len(self.get_pending_tasks())
        completed_tasks = len(self.get_completed_tasks())
        overdue_tasks = len(self.get_overdue_tasks())

        print(f"待完成任务数量: {pending_tasks}")
        print(f"已完成任务数量: {completed_tasks}")
        print(f"过期任务数量: {overdue_tasks}")

def log_activity(func):
    def wrapper(*args, **kwargs):
        print(f"执行 {func.__name__} 于 {datetime.datetime.now()}")
        result = func(*args, **kwargs)
        print(f"完成执行 {func.__name__}")
        return result
    return wrapper

@log_activity
def main():
    task_manager = TaskManager()

    task_manager.add_task("买杂货", "牛奶, 面包, 奶酪", datetime.date(2024, 7, 15))
    task_manager.add_task("完成作业", "完成数学作业", datetime.date(2024, 7, 10))
    task_manager.add_task("打扫房间", "客厅和厨房", datetime.date(2024, 7, 20))

    print("所有任务:")
    for task in task_manager.tasks:
        print(task)

    print("\n待完成任务:")
    for task in task_manager.get_pending_tasks():
        print(task)

    print("\n将'完成作业'标记为已完成。")
    for task in task_manager.tasks:
        if task.title == "完成作业":
            task.mark_completed()

    print("\n已完成任务:")
    for task in task_manager.get_completed_tasks():
        print(task)

    print("\n过期任务:")
    for task in task_manager.get_overdue_tasks():
        print(task)

    print("\n移除'买杂货'任务。")
    task_manager.remove_task("买杂货")

    print("\n移除后的所有任务:")
    for task in task_manager.tasks:
        print(task)

    print("\n任务总结:")
    task_manager.summary()

    print(f"\n全局变量 tasks_completed 的值是: {tasks_completed}")

if __name__ == "__main__":
    main()

8.1 代码说明
  1. 任务类 Task
    • __init__ 方法初始化任务的标题、描述、截止日期和完成状态。
    • mark_completed 方法使用 global 关键字修改全局变量 tasks_completed,标记任务为已完成。
    • __str__ 方法返回任务的字符串表示,包括标题、状态

和截止日期。

  1. 任务管理类 TaskManager

    • __init__ 方法初始化任务列表。
    • add_task 方法添加新任务到任务列表。
    • remove_task 方法从任务列表中移除指定标题的任务。
    • get_pending_tasks 方法获取所有未完成的任务。
    • get_completed_tasks 方法获取所有已完成的任务。
    • get_overdue_tasks 方法获取所有过期未完成的任务。
    • summary 方法输出待完成任务、已完成任务和过期任务的数量。
  2. 装饰器 log_activity

    • 装饰器函数记录函数执行的时间和日志信息。
  3. 主函数 main

    • 包含任务管理系统的主要逻辑,包括添加任务、标记任务为完成、获取任务列表、移除任务和输出任务总结。
8.2 运行结果

在这里插入图片描述

9. 结论

理解和掌握Python中变量的作用域是编写高效代码的关键。通过本文的详细解释和综合示例,希望读者能够更好地理解局部变量和全局变量的概念及其使用方法。在实际编程中,正确地管理变量的作用域可以提高代码的可读性和维护性,避免不必要的错误。


欢迎点赞|关注|收藏|评论,您的肯定是我创作的动力

  • 37
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值