首页
学习
活动
专区
圈层
工具
发布
社区首页 >专栏 >python 作用域、闭包、装饰器(3.2)

python 作用域、闭包、装饰器(3.2)

作者头像
友儿
发布于 2022-09-28 13:21:53
发布于 2022-09-28 13:21:53
9260
举报
文章被收录于专栏:友儿友儿

作用域

程序创建, 访问, 改变一个变量时, 都是在一个保存该变量的空间内进行, 这个空间被称为命名空间, 即作用域

Built-in 内置

  • 可以在Python环境中的任何模块, 任意位置访问和调用

Global 全局变量

只作用于当前模块(可以理解为当前文件)

可以简单地理解为定以在函数外的变量就是全局变量, 如果在函数体定义那就时局部变量.

如何将局部变量变成全局变量?

使用global关键字

代码语言:javascript
复制
a = 1

def foo():
    global a
    a = 2
    print(a)

foo()
print(a)

Enclosed(嵌套) 自由变量

在嵌套函数中, 访问函数体之外的非全局变量

只作用于嵌套函数体

最大的应用就是闭包

自由变量是个相对的概念

将局部变量变成自由变量

使用nonlocal关键字

代码语言:javascript
复制
def make_averager():
    total = 0
    count = 0
    def averager(value):
        nonlocal total, count
        total += value
        count += 1
        return total / count
    return averager
    
my_avg = make_averager()
print(my_avg(1))
print(my_avg(2))

Local局部变量

只作用于当前函数体

一旦变量在函数体中赋值, 那么该变量相对该函数来说就是局部变量

代码语言:javascript
复制
a = 1
b = []


def foo():
    a = 2
    b.append(2)
    # 局部变量会在函数声明的时候就定义好
    # 不是按照我们逻辑思维上先执行全局变量b.append(2), 然后再声明一个局部变量b
    # 而是再函数声明之初就已经定义了b为局部变量
    # b = 3
    return None

foo()
print(a)
print(b)

闭包和装饰器

闭包

闭包指延申了作用域的函数, 也就是作用域中的Enclosed的概念

代码语言:javascript
复制
def make_averager():
    series = []
    def averager(value):
        series.append(value)
        total = sum(series)
        return total / len(series)
    return averager

# my_avg就是延申了作用域的函数
# series就是被延申作用域的变量
my_avg = make_averager()
print(my_avg(1))
print(my_avg(2))

装饰器

实现原理

就是闭包, 延申了被装饰函数的作用域, 本质是将函数作为参数传递给一个可调用对象(函数或类)

目的

增加和扩展可调用对象(函数或类)的行为

实现一个装饰器

通过@关键字装饰函数

代码语言:javascript
复制
def clock_it_deco(func):
    def wrapper(*args, **kwargs):
        start_time = time.time()
        result = func(*args, **kwargs)
        end_time = time.time()
        print(f"{func.__name__} execute time: {format(end_time - start_time, '.2f')} s")
        return result
    return wrapper

# @other_deco
@clock_it_deco
def foo(a, b):
    count = 1
    while True:
        if count > a ** b:
            break
        count += 1

foo(10, 5)

等同于

代码语言:javascript
复制
foo = clock_it_deco(foo)
foo(10, 5)
本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2022 年 09 月,如有侵权请联系 cloudcommunity@tencent.com 删除
目录
  • 作用域
  • 闭包和装饰器
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档