python 装饰器(Decorators)原理说明

python装饰器底层原理讲解 文章目录1 python装饰器的作用2 python装饰器的原理3 python装饰器的实现3.1 最简陋的装饰器4 python装饰器在自动化测试框架中的应用从一个需求开始 1 python装饰器的作用 被装饰对象获得了更强大的功能 2 python装饰器的原理 python装饰器本身是一个函数 这个函数的参数是一个函数对象 这个函数的返回值也是一个函数对象,这个函数的功能更强大 python装饰器是python的一个语法糖(更简便的语法) 3 python装饰器的实现 3.1 最简陋的装饰器 ''' 阅读详情

本文目的是由浅入深地介绍python装饰器原理

装饰器(Decorators)是 Python 的一个重要部分

其功能是, 在不修改原函数(类)定义代码的情况下,增加新的功能

为了理解和实现装饰器,我们先引入2个核心操作:

1 必要的2个核心操作

1.1 核心操作1, 函数内部可以定义函数

def hi(name='world'):
    print(f"hello, {name}")

    def howdoyoudo(name2=name):
        print(f"how do you do? {name2}")

    howdoyoudo()
    howdoyoudo('world')
    
hi("ytt") # 但是新函数还是存在的。
hi("ycy") # 但是新函数还是存在的。

try:
    howdoyoudo()
except:
    print("function not found")

在这个例子中,函数hi的形参name,默认为'world'

在函数内部,又定义了另一个函数 howdoyoudo,定义这个函数时,将形参name作为新函数的形参name2的默认值。

因此,在函数内部调用howdoyoudo()时,将以调用hi时的实参为默认值,但也可以给howdoyoudo输入其他参数。

上面的例子运行后输出结果为:

hello, ytt  how do you do? ytt  how do you do? world  hello, ycy  how do you do? ycy  how do you do?  worldfunction not found

这里新定义的howdoyoudo可以称作一个“闭包”。不少关于装饰器的blog都提到了这个概念,但其实没必要给它取一个多专业的名字。我们知道闭包是 函数内的函数 就可以了

1.2 核心操作2 函数可以作为对象被输入输出

1.2.1 核心操作2的前置条件,函数是对象

当我们进行 def 的时候,我们在做什么?

def hi():
    print("hi")
    return "world"

这时,hi函数,打印一个字符串,同时返回一个字符串。

但hi函数本身也是一个对象,一个可以执行的对象。执行的方式是hi()。

这里hi和hi()有本质区别,

hi 代表了这个函数对象本身

hi() 则是运行了函数,得到函数的返回值。

def hi(name='world'):
    print(f"hello, {name}")
    return name
msg = hi()  # 运行函数,返回字符串,因此msg是个字符串
print(msg)
hello = hi  # 将函数本身赋值给hello,此时hello是另一个函数,即使删除原函数hi,新函数hello也可以正常调用
del hi  # 删除原函数hi
try:
    hi()
except:
    print("func hi not found")
hello("ycy") # 但是新函数还是存在的。

作为对比,可以想象以下代码

a = 'example'
b = a 
del a

此时也是b存在,可以正常使用。

1.2.2函数作为输入

我们定义2个函数,分别实现自加1, 自乘2,

再定义一个函数double_exec,内容是将某个函数调用2次

在调用double_exec时,可以将函数作为输入传进来

def func1(n):
    return n+1
    
def func2(n):
    return n*2
    
def double_exec(f,x):
    return f(f(x))    
    
rst = double_exec(func1, 5)
print(rst)
rst = double_exec(func2, 3)
print(rst)

输出结果就是

7

27

1.2.3 函数作为输出

同样,也可以将函数作为输出

def select_func(i):
    def func1(n):
        return n+1

    def func2(n):
        return n*2
    func_list = [func1, func2]    
    return func_list[i]
    
func = select_func(0)  # 第1个函数
print(func(5))
func = select_func(1)  # 第2个函数
print(func(5))

输出结果为

6

10

2 尝试构造装饰器

有了以上两个核心操作,我们可以尝试构造装饰器了。

装饰器的目的: 在不修改原函数(类)定义代码的情况下,增加新的功能

试想一下,现在有一个原函数

def original_function:
    print("this is original function")

在不修改原函数定义代码的情况下,如果想进行函数内容的添加,可以将这个函数作为一个整体,添加到这样的包裹中:

def my_decorator(f):
    def wrap_func():
        print(f"before call {f.__name__}")
        f()
        print(f"after call {f.__name__}")
    return wrap_func
new_function = my_decorator(original_function)

我们定义了一个my_decorator函数,这个函数进行了一种操作:

对传入的f,添加操作(运行前后增加打印),并把添加操作后的内容连同运行原函数的内容,一起传出

这个my_decorator,定义了一种增加前后打印内容的行为

调用my_decorator时,对这个行为进行了操作。

因此,new_function是一个在original_function上增加了前后打印行为的新函数

这个过程被可以被称作装饰。

例子中的对象角色说明
wrap闭包函数重新定义了一种格式,这个格式可以任意的,是装饰器的真正内容
my_decorator装饰器定义了按warp这种格式进行操作的函数
f待装饰函数(形参)在定义装饰器时,待装饰函数只是一个参数
original_function实际进行装饰的函数一个具体的需要装饰的函数
new_function装饰后的函数一个具体的装饰完成的函数

这里已经可以发现,装饰器本身对于被装饰的函数是什么,是不需要考虑的。装饰器本身只定义了一种装饰行为,这个行为是通过装饰器内部的闭包函数()进行定义的。

运行装饰前后的函数,可以清晰看到装饰的效果

def original_function():
    print("this is original function")
    
def my_decorator(f):
    def wrap_func():
        print(f"before calling {f.__name__}")
        f()
        print(f"after calling {f.__name__}")
    return wrap_func


new_function = my_decorator(original_function)
original_function()
print("#########")
new_function()

3装饰器定义的简写

我们复现一下实际要用装饰器的情况,我们往往有一种装饰器,想应用于很多个函数,比如

def my_decorator(f):
    def wrap_func():
        print(f"before calling {f.__name__}")
        f()
        print(f"after calling {f.__name__}")
    return wrap_func

def print1():
    print("num=1")
def print2():
    print("num=2")
def print3():
    print("num=3")

此时,如果我们想给3个print函数都加上装饰器,需要这么做

new_print1 = my_decorator(print1)
new_print2 = my_decorator(print2)
new_print3 = my_decorator(print3)

实际调用的时候,就需要调用添加装饰器的函数名了

new_print1()
new_print2()
new_print3()

当然,也可以赋值给原函数名

print1 = my_decorator(print1)
print1 = my_decorator(print2)
print3 = my_decorator(print3)

这样至少不需要管理一系列装饰前后的函数。

同时,在不需要进行装饰的时候,需要把

print1 = my_decorator(print1)
print1 = my_decorator(print2)
print3 = my_decorator(print3)

全部删掉。

事实上,这样并不方便,尤其对于更复杂的装饰器来说

为此,python提供了一种简写方式

def my_decorator(f):
    def wrap_func():
        print(f"before calling {f.__name__}")
        f()
        print(f"after calling {f.__name__}")
    return wrap_func

@my_decorator
def print1():
    print("num=1")

这个定义print1函数前的@my_decorator,相当于在定义完print1后,自动直接运行了

print1 = my_decorator(print1)

一个新的麻烦及解决办法

不论采用@my_decorator放在新函数前,还是显示地重写print1 = my_decorator(print1),都会存在一个问题:

装饰后的函数,名字改变了(其实不止名字,一系列的索引都改变了)

def print1():
    print("num=1") 
    
print(f"before decorate, function name: {print1.__name__}")
print1 = my_decorator(print1)
print(f"after decorate, function name: {print1.__name__}")

输出结果为:

before decorate, function name: print1  after decorate, function name: wrap_func

这个现象的原因是,装饰行为本身,是通过构造了一个新的函数(例子中是wrap_func函数)来实现装饰这个行为的,然后把这个修改后的函数赋给了原函数名。

这样,会导致我们预期的被装饰函数的一些系统变量(比如__name__)发生了变化。

对此,python提供了解决方案:

from functools import wraps  # 导入一个系统工具
def my_decorator(f):
    @wraps(f)  # 在定义装饰行为函数的时候,增加一个新的装饰器
    def wrap_func():
        print(f"before calling {f.__name__}")
        f()
        print(f"after calling {f.__name__}")
    return wrap_func

经过这个行为后,被装饰函数的系统变量问题被解决了

def print1():
    print("num=1") 
    
print(f"before decorate, function name: {print1.__name__}")
print1 = my_decorator(print1)
print(f"after decorate, function name: {print1.__name__}")

输出结果为

before decorate, function name: print1  after decorate, function name: print1

当然,如果你不需要使用一些系统变量,也可以不关注这个问题。

复杂一点的情况1 被装饰函数有输入输出

刚才的例子都比较简单,被装饰的函数是没有参数的。如果被装饰的函数有参数,只需要在定义装饰行为时(事实上,这个才更通用),增加(*args, **kwargs)描述即可

from functools import wraps  
def my_decorator(f):
    @wraps(f)  
    def wrap_func(*args, **kwargs):  # 增加了输入参数
        print(f"before calling {f.__name__}")
        ret = f(*args, **kwargs)  # 透传了输入参数,并记录了输出
        print(f"after calling {f.__name__}") # line-after
        return ret  # 执行 "line-after" 后,将f的输出返回
    return wrap_func

之前的描述中可以感受到,对于例子中的装饰行为(前后加打印),函数被装饰后,本质上是调用了新的装饰函数wrap_func。

因此,如果原函数需要有输入参数传递,只需要在wrap_func(或其他任意名字的装饰函数)定义时,也增加参数输入(*args, **kwargs),并将这些参数,原封不动地传给待装饰函数f。

这种定义装饰行为的方式更具有普遍性,忘记之前的定义方式吧

我们试一下

@my_decorator
def my_add(x, y):
    return x + y
    
n = my_add(1, 3)
print(n)

输出

before calling my_add  after calling my_add  4

这里需要注意的是,如果按照以下的方式定义装饰器

from functools import wraps  
def my_decorator(f):
    @wraps(f)  
    def wrap_func(*args, **kwargs):  # 增加了输入参数
        print(f"before calling {f.__name__}")
        return f(*args, **kwargs)  # 透传了输入参数,并记录了输出
        print(f"after calling {f.__name__}") # line-after        
    return wrap_func

那么以下语句将不会执行

print(f"after calling {f.__name__}") # line-after

因为装饰后实际的函数wrap_func(虽然名字被改成了原函数,系统参数也改成了原函数),运行到return f(*args, **kwargs) 的时候已经结束了

复杂一点的情况2 装饰器有输入

因为装饰器my_decorator本身也是可以输入的,因此,只需要在定义装饰器时,增加参数,并在后续函数中使用就可以了,比如

from functools import wraps  
def my_decorator(f, msg=""):
    @wraps(f)  
    def wrap_func(*args, **kwargs):  # 增加了输入参数
        print(f"{msg}, before calling {f.__name__}")
        return f(*args, **kwargs)  # 透传了输入参数,并记录了输出
        print(f"{msg}, after calling {f.__name__}") # line-after        
    return wrap_func

此时装饰器已经可以有输入参数了

def my_add(x, y):
    return x + y

my_add = my_decorator(my_add, 'yusheng')
    
n = my_add(1, 3)
print(n)

输出

yusheng, before calling my_add  yusheng, after calling my_add  4

你可能发现,为什么不用简写版的方法了

@my_decorator(msg='yusheng')
def my_add(x, y):
    return x + y
    
n = my_add(1, 3)
print(n)

因为以上代码会报错!!

究其原因,虽然

@my_decorator
def my_add(x, y):
    return x + y

等价于

def my_add(x, y):
    return x + y
my_add = my_decorator(my_add)

但是,

@my_decorator(msg='yusheng')
def my_add(x, y):
    return x + y

并不等价于

def my_add(x, y):
    return x + y
my_add = my_decorator(my_add, msg='yusheng')

这本身和@语法有关,使用@my_decorator时,是系统在应用一个以单个函数作为参数的闭包函数。即,@是不能带参数的。

但是你应该发现了,之前的@wraps(f)不是带参数了吗?请仔细观察以下代码

def my_decorator_with_parma(msg='')
    def my_decorator(f):
        @wraps(f)  
        def wrap_func(*args, **kwargs):  # 增加了输入参数
            print(f"{msg}, before calling {f.__name__}")
            return f(*args, **kwargs)  # 透传了输入参数,并记录了输出
            print(f"{msg}, after calling {f.__name__}") # line-after        
        return wrap_func
    return my_decorator

通过一层嵌套,my_decorator_with_parma本质上是返回了一个参数仅为一个函数的函数(my_decorator),但因为my_decorator对my_decorator_with_parma来说是一个闭包,my_decorator_with_parma是可以带参数的。(这句话真绕)

通过以上的定义,我们再来看

@my_decorator_with_parma(msg='yusheng')
def my_add(x, y):
    return x + y

可以这么理解,my_decorator_with_parma(msg='yusheng')的结果是原来的my_decorator函数,同时,因为my_decorator_with_parma可以传参,参数实际上是参与了my_decorator的(因为my_decorator对my_decorator_with_parma是闭包), my_decorator_with_parma(msg='yusheng') 全等于 一个有参数参加的my_decorator

因此,以上代码等价于有参数msg传递的

@my_decorator
def my_add(x, y):
    return x + y

比较绕,需要理解一下,或者干脆强记这种范式:

from functools import wraps  
def my_decorator(msg=''):  # 名字改一下
    def inner_decorator(f):  # 名字改一下
        @wraps(f)  
        def wrap_func(*args, **kwargs):  # 增加了输入参数
            print(f"{msg}, before calling {f.__name__}")
            ret = f(*args, **kwargs)  # 透传了输入参数,并记录了输出
            print(f"{msg}, after calling {f.__name__}") # line-after        
            return ret
        return wrap_func
    return inner_decorator

以上范式包含函数的输入输出、装饰器的输入,可以应对大部分情况了。

实验一下:

@my_decorator(msg='yusheng')
def my_add(x, y):
    return x + y

my_add(1, 2)

输出

yusheng, before calling my_add  yusheng, after calling my_add

有用的函数装饰器例子

统计耗时的日志

from functools import wraps
import datetime

def log(output_path=None):  # 名字改一下
    def decorator(f):  # 名字改一下
        @wraps(f)  
        def wrap_func(*args, **kwargs):  # 增加了输入参数
            now = datetime.datetime.now()
            msg = now.strftime("%Y-%m-%d %H:%M:%S")  # 运行时刻
            msg += f" {f.__name__}()\n"  # 运行的函数名            

            ret = f(*args, **kwargs)  # 透传了输入参数,并记录了输出

            aft = datetime.datetime.now()
            time_cost = aft - now
            ms = time_cost.total_seconds() * 10**3  # 毫秒
            msg += now.strftime("%Y-%m-%d %H:%M:%S")
            msg += f" {f.__name__}() return, cost {ms} ms"
            if output_path is None:
                print(msg)
            else:
                print(f"print logs into {output_path}")
                with open(output_path, 'a+') as fp:
                    fp.write(msg + '\n')
        return wrap_func
    return decorator

以上是一个log装饰器,利用datetime统计了函数的耗时,

并且,装饰器可以进行输出文件操作,如果给出了文件路径,则输出文件,否则就打印。

利用这个装饰器,可以灵活地进行耗时统计

@log()
def my_sum(x, y):
    s = 0
    for i in range(x, y+1):
        s += i
    return s
    
my_sum(1, 9999999)

不设置输出文件地址,则打印。运行结果为:

2021-12-03 10:01:52 my_sum()  2021-12-03 10:01:52 my_sum() return, cost 506.3299999999999 ms

也可以输出到文件

@log('test.log')
def my_sum(x, y):
    s = 0
    for i in range(x, y+1):
        s += i
    return s   

my_sum(1, 9999999)

输出结果为

print logs into test.log

同时在当前目录生成了一个test.log 文件,内容为:

2021-12-03 10:03:17 my_sum()  2021-12-03 10:03:17 my_sum() return, cost 461.813 ms

从装饰函数到装饰类

以上的装饰器都是以函数形式出现的,但我们可以稍做改写,将装饰器以类的形式实现。

from functools import wraps
import datetime
class Log:
    def __init__(self, path=None):
        self._output = path
        
    def __call__(self, f):  # 相当于原来的 inner_decorator
        @wraps(f)  
        def wrap_func(*args, **kwargs):  # 增加了输入参数
            now = datetime.datetime.now()
            msg = now.strftime("%Y-%m-%d %H:%M:%S")  # 运行时刻
            msg += f" {f.__name__}()\n"  # 运行的函数名            

            ret = f(*args, **kwargs)  # 透传了输入参数,并记录了输出

            aft = datetime.datetime.now()
            time_cost = aft - now
            ms = time_cost.total_seconds() * 10**3  # 毫秒
            msg += now.strftime("%Y-%m-%d %H:%M:%S")
            msg += f" {f.__name__}() return, cost {ms} ms"
            if self._output is None:
                print(msg)
            else:
                print(f"print logs into {self._output}")
                with open(self._output, 'a+') as fp:
                    fp.write(msg + '\n')
        return wrap_func

这个装饰器类Log 上个例子里的装饰器函数log功能是一样的,同时,这个装饰器类还可以作为基类被其他继承,进一步增加功能。

Python装饰器:从基础到高级的全面指南 装饰器本质上是一个可调用对象(通常是一个函数),它接受另一个函数作为参数,并返回一个新的函数。这个新函数通常会在执行原始函数前后添加一些额外的功能。print("Something is happening before the function is called.") # 在调用原函数之前执行的代码func() # 调用原始函数print("Something is happening after the function is called.") # 在调用原函数之后执行的代码。 阅读详情

相关推荐

Python装饰器从入门到进阶:原理、实战与避坑指南

在Python编程中,函数作为一等公民,可以像普通对象一样被赋值、传递和返回,这正是理解高阶函数与闭包的基础。装饰器正是基于这一机制,通过闭包在函数调用前后注入通用逻辑,实现日志埋点、性能统计、结果缓存、重试机制等能力。掌握装饰器的写法与执行时机,能显著提升代码复用性与可维护性。本文从函数对象与闭包的本质讲起,剖析@语法糖的执行原理,梳理函数装饰器、带参装饰器、类装饰器以及functools.wraps的用法,并结合日志、缓存、权限校验等真实业务场景,帮助读者透彻理解Python装饰器的工程实践与常见陷阱。

weixin_29306317的博客 300

python语言:装饰器原理

装饰器是 Python 的重要组成部分。简而言之:它们是修改其他功能的功能。它们有助于使我们的代码更短、更 Pythonic。大多数初学者不知道在哪里使用它们,所以我将分享一些装饰器可以让你的代码更简洁的地方。这可能是最难掌握的概念之一。我们将一步一步地进行,以便您完全理解它。 ...

gongdiwudu的专栏 6836

深入理解Python中的装饰器(Decorators):从基础到高级应用

Python装饰器是一个强大的工具,它使得在不修改原有函数代码的情况下增加额外功能成为可能。从基础的概念理解到高级应用,装饰器极大地提高了代码的模块化和可重用性。掌握装饰器的使用,对于编写高质量、易于维护的Python代码至关重要。希望本文能帮助您更好地理解和应用Python装饰器。

m0_38123128的博客 1万+

python中装饰器的工作原理

Python装饰器

little_limin的博客 1211

Python中的装饰器(Decorators)及其应用场景

在Python编程中,装饰器(Decorators)是一个强大且灵活的工具,它允许我们在不修改函数或类代码的情况下,为其添加额外的功能或修改其行为。装饰器本质上是一个接受函数作为参数的可调用对象(通常是函数或类),并返回一个新的函数对象。这个符号会将紧跟其后的函数对象作为参数传递给装饰器函数,并将装饰器函数的返回值(通常是一个新的函数对象)重新绑定到原函数的名称上。:装饰器可以用于实现函数的缓存机制,将函数的计算结果存储起来,以便在下次调用时直接使用缓存结果,提高代码的执行效率。一、装饰器的基本概念。

铭渊老黄 982

STM32+HX711实战:5分钟搞定拉力传感器数据采集(附完整代码)

本文详细介绍了如何使用STM32微控制器和HX711模数转换器快速搭建高精度拉力测量系统。通过硬件连接指南、驱动实现代码和校准方法,帮助开发者在5分钟内完成拉力传感器数据采集,适用于工业自动化和消费电子等场景。

y7z8a9的博客 874

【低门槛 手把手】python 装饰器(Decorators)原理说明

本文目的是由浅入深地介绍python装饰器原理 装饰器(Decorators)是 Python 的一个重要部分 其功能是, 在不修改原函数(类)定义代码的情况下,增加新的功能 为了理解和实现装饰器,我们先引入2个核心操作: 1 必要的2个核心操作 1.1 核心操作1, 函数内部可以定义函数 def hi(name='world'): print(f"hello, {name}") def howdoyoudo(name2=name): print(f"how do you

m0_64519234的博客 314

【TensorRT】TensorRT C# API 项目介绍:基于C#与TensorRT部署深度学习模型(上篇)

开发了TensorRT C# API 2.0版本,该版本在开发时充分考虑了上一版本应用时出现的问题,并进行了改进。同时在本版本中,我们对接口进行了优化,使用起来更加简单,并同时提供了相关的应用案例,方便开发者进行使用。

grape_yan的博客 3038

Decorators-Primer on Python Decorators 装饰器入门

Decorators-Primer on Python Decorators 装饰器入门

labmem012的博客 1187

NX/UG二次开发—CAM—设置程序修剪边界Boundary

最近做了一个设置CAM程序边界的小工具,分享一下经验(官方的代码在文章末尾处),以下均以修剪边界曲线为例。 以下为官方提供的源码: /***************************** Include Files **********************************/ #include <stdlib.h> #include <uf.h> #include <uf_obj.h> #include <uf_object_type

门前大桥下,游过一群鸭,快来看一看,原来是C++ 3733

18、未来医疗信息学中的太赫兹天线技术

本文探讨了太赫兹天线技术在医疗信息学中的关键作用,重点分析了分裂环谐振器和纳米结构光导天线(PCA)的设计与性能提升方法,介绍了相干与非相干太赫兹检测技术,并通过等效电路模型和数值模拟深入解析PCA工作机理。文章还展示了太赫兹技术在无创血糖监测、肿瘤检测等医疗诊断中的实验应用,总结了其非侵入性、高分辨率成像和多参数分析等优势,同时指出信号检测难、成本高和技术复杂等挑战。未来趋势包括设备小型化、效率提升及与人工智能融合,拓展至药物研发、皮肤与神经疾病诊断等领域,展现出变革医疗健康的巨大潜力。

milk8的博客 146

函数装饰器(Decorators)详解 | Python

装饰器(Decorators)是 Python 的一个重要部分。简单地说:他们是修改其他函数的功能的函数。他们有助于让我们的代码更简短,也更Pythonic(Python范儿)。大多数初学者不知道在哪儿使用它们,所以我将要分享下,哪些区域里装饰器可以让你的代码更简洁。 首先,让我们讨论下如何写你自己的装饰器。 这可能是最难掌握的概念之一。我们会每次只讨论一个步骤,这样你能完全理解它。 一切皆对象 def hi(name="yasoob"): return "hi " + name print(hi

用途:中英文学习笔记,如有侵权,可评论留言,及时清理;学历:NUS计算机硕士;SYSU地球物理学士 1984

漫画安全HIDS、EDR、NDR、XDR

漫画安全HIDS、EDR、NDR、XDR

墨痕诉清风的博客 3446

Python 装饰器 (Decorators):深度解析、应用与最佳实践

Python装饰器是一种高级函数,允许在不修改原函数代码的情况下为其添加额外功能。其核心思想是利用Python函数作为"一等公民"的特性(可赋值、传递、返回),通过闭包和内部函数实现功能扩展。装饰器基本形式包含一个接收函数并返回新函数的函数,使用@语法糖简化应用。进阶用法包括处理函数参数的*args和**kwargs,以及通过多层嵌套实现带参数的装饰器。装饰器能优雅地实现性能分析、权限控制、日志记录等横切关注点,提高代码复用性和可维护性。

weixin_42107409的博客 1350

YOLOv8 | 损失函数改进,最新提出的Shape-IoU,有效涨点

作为检测器定位分支的重要组成,边框回归损失在目标检测任务中发挥巨大作用。现有的边框回归方法,通常考虑了GT框与预测框之间的几何关系,通过使用边框间的相对位置与相对形状等计算损失,而忽略了边框其自身的形状与尺度等固有属性对边框回归的影响。为了弥补现有研究的不足,本文提出聚焦边框自身形状与尺度的边框回归方法。首先我们对边框回归特性进行分析,得出边框自身形状因素与尺度因素会对回归结果产生影响。

kay_545 1913

python decorators_python装饰器Decorators

本人在www.programiz.com网站上搜到一篇讲解python装饰器的文章,由浅入深,步步深入,可以一读。声明:此篇文章是从programiz.com网站摘录得到的,并非本人原创。原来为英文版本,本人翻译成中文版本,并加了部分批注,如有错误还请指正。Python DecoratorsA decorator takes in a function, adds some functionali...

weixin_39822993的博客 228

WINCC7.3破解文件

WINCC7.3硬件够破解文件,有需要的下载!WINCC7.3硬件够破解文件,有需要的下载!

Decorators 装饰器

Everything in Python is an object: First of all let’s understand functions in Python: def hi(name="yasoob"): return "hi " + name print(hi()) 参考: http://book.pythontips.com/en/latest/decorators.h...

u013657997的博客 2482

蓝牙模块HM-10手册

蓝牙模块HM-10手册,该手册对蓝牙模块HM-10进行了详细的介绍和使用方法以及一些AT指令。

efm32 入门.pdf

本PDF共计22页,介绍的是操作驱动API,下载与否自己斟酌。

python 装饰器(Decorators)介绍

为什么要装饰器 假设现在程序实现了say_hello()和say_goodbye()两个函数。 import time def say_hello(): time.sleep(1) print("say_hello!") def say_goodbye(): time.sleep(1) print("say_goodbye!") # bug here i...

别动我名字 628

怀旧版电脑GBC模拟器

再现原版GBC掌机的界面,电脑运行连游戏界面都一样大小,很怀旧,很真实,(英文版)强烈推荐,很小的文件,很难才找到的。

聊聊Python的装饰器(Decorators)

为了更好的理解Decorators(装饰器),首先要理解什么是function(函数/方法)? 函数就是 一段代码块, 它基于给定的传入参数,返回有意义的值,或者执行特定的操作。 比如: def test_add(a, b): return a + b 在Python中, 函数也是一种对象,所以本身也可以作为函数的传入参数来使用,这就为装饰器的产生提供了必要的条件, Decorato...

324

轻松理解Python--装饰器(Decorators)

其实最主要的是在我们之前定义的wrapper函数中,我们使用fun = func()这里的时候就没有给func()传参数,但是现在问题来了,如果我的func原本就需要参数,且多个func都需要加入修饰器,每个func的参数个数还不一样,那怎么办呢?现在func函数已经写好了,我们需要增加一个功能,就是在输入之前要给一个提示信息,告诉用户现在应该输入x的值了,在不改变原函数代码的情况下,这个问题该如何解决呢?在Python中,装饰器的作用定义为:在不改变原函数代码的前提下,给原函数增加新的功能。

m0_64893992的博客 645

什么是装饰器?以Python为例:Basic Usage of Decorators (中英双语)

When using the @decorator syntax, Python applies the decorator to the function during the loading phase.The original function is replaced with the new function returned by the decorator.

阿正的梦工坊 1411

Python 装饰器(Decorators) 超详细分类实例

Python装饰器分类 Python 装饰器函数: 是指装饰器本身是函数风格的实现; 函数装饰器: 是指被装饰的目标对象是函数;(目标对象); 装饰器类 : 是指装饰器本身是类风格的实现; 类装饰器 : 是指被装饰的目标对象是类;(目标对象); 装饰器函数 目标对象是函数 (1)、装饰器无参数 A、目标无参数 strOldFunctionName = ""; s...

不止于Python 473

Python基础 —— 装饰器[decorators]

装饰器 [decorators] 概念: 装饰器本质是一个函数,主要用来修饰另一个函数或者类。 作用: 在不修改被装饰函数的内容 和 不改变被装饰函数的调用方式 为前提,添加或改变原函数的功能。 参数和返回值: 传入的是一个函数,返回的也是一个函数。 说明: 装饰器需要用闭包实现,内部函数要注意形参列表一致(数量和类型)。 多个装饰器修饰,贴的近的先装饰。 语法: def deco_fn(fx):...

风居住的街道 195

Python笔记 · 函数装饰器(Decorators)

如果我们想为这个函数,也包括所有其他函数添加一个自动日志的功能,以便记录一下函数调用前后的时间,这是一个典型的“横切”场景,实际上,更加具有实际应用价值的一个案例是:在方法调用前启动一个事务,在方法执行完毕后提交一个事务,此类是更加典型的案例。首先,我们要注意一下这个log的函数的整体“框架”:它先在函数体内定义了一个子函数warp,然后log函数最终返回的其实是wrap函数。至此,“朴素版”的装饰器函数log就算实现完成了,由于类似的装饰场景普遍存在,Python在语法层面上提升了对这一模式的支持力度,

Laurence的技术博客 816
上一篇: 超有趣的Python实战:将图片转成像素风
下一篇: Python 实现循环的最快方式(for、while 等速度对比)
Python_xiaowu
博客等级 码龄5年 3096粉丝 178原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值