python 装饰器之自定义装饰器

一 装饰器的原理及作用

原理:闭包的使用
作用:在不改变原有函数代码的前提下,为函数增添功能

二 函数作为装饰器

无参装饰器,被修饰的是普通函数
from functools import wraps

def ourter(func):
    @wraps(func)
    def inner(*args, **kwargs):
        return func(*args, **kwargs)
    return inner 

@ourter
def test(name):
    print(f'测试无参数的装饰器 {name}')

test('大番茄')
print(test.__name__)

## 输出结果
# 测试无参数的装饰器 大番茄
# test
无参装饰,被修饰的是类
from functools import wraps

def outer(cls):
    cls.num = 10
    print(cls)
    return cls

@outer
class animal:
    
    def __init__(self, name) -> None:
        self.name = name

a = animal(name='zhangsan')
print(a.num)
print(a.name)

##输出结果
# <class '__main__.animal'>
# 10
# zhangsan
无参装饰器,被修饰的是类中的方法
from functools import wraps
def outer(func):
    @wraps(func)
    def inner(self, *args, **kwargs):
        func(self, *args, **kwargs)
    return inner

class animal:
    
    def __init__(self, name):
        self.name = name
    
    @outer
    def say(self):
        print(f'我叫 {self.name}')

a = animal(name='zhangsan')
a.say()
print(a.say.__name__)

## 输出结果
# 我叫 zhangsan
# say
有参装饰器,被修饰的是普通函数
from functools import wraps

def newouter(*args, **kwargs):
    print('获取装饰器中的参数')
    print(args)
    print(kwargs)
    def ourter(func):
        @wraps(func)
        def inner(*args, **kwargs):
            return func(*args, **kwargs)
        return inner 
    return ourter

@newouter(name='zhangsan', age=12)
def test(name):
    print(f'测试无参数的装饰器 {name}')

test('大番茄')
print(test.__name__)

## 输出结果
# 获取装饰器中的参数
# ()
# {'name': 'zhangsan', 'age': 12}        
# 测试无参数的装饰器 大番茄
# test
有参装饰器,被修饰的是类
from functools import wraps

def newouter(*args, **kwargs):
    print('获取装饰器参数')
    print(args)
    print(kwargs)
    def outer(cls):
        cls.num = 10
        print(cls)
        return cls
    return outer
    
@newouter(is_true=True, is_false=False)
class animal:
    
    def __init__(self, name) -> None:
        self.name = name

a = animal(name='zhangsan')
print(a.num)
print(a.name)

## 输出结果
# 获取装饰器参数
# ()
# {'is_true': True, 'is_false': False}   
# <class '__main__.animal'>
# 10
# zhangsan
有参装饰器,被修饰的是类中的方法
from functools import wraps

def title(name):
    def outer(func):
        @wraps(func)
        def inner(self, *args, **kwargs):
            print(name)
            func(self, *args, **kwargs)
        return inner
    return outer
    

class animal:
    
    def __init__(self, name) -> None:
        self.name = name

    @title('开口说话')
    def say(self):
        print(f'我叫 {self.name}')

a = animal(name='zhangsan')
a.say()
print(a.say.__name__)

## 输出结果
# 开口说话
# 我叫 zhangsan
# say

三 类中的方法作为装饰器

class TestDeracotorClasss:

    def deracotor_1(self, func):
        def inner(*args, **kwargs):
            print('装饰1开始')
            func(*args, **kwargs)
            print('装饰1结束')
            print('--------------------------')
        return inner

    def derancotor_2(func):
        def inner(self, *args, **kwargs):
            print('装饰2开启')
            func(self, *args, **kwargs)
            print('装饰2关闭')
            print('--------------------------')
        return inner
    
    @staticmethod
    def derancotor_3(func):
        def inner(self, *args, **kwargs):
            print('开始装饰3')
            func(self, *args, **kwargs)
            print('结束装饰3')
            print('--------------------------')
        return inner

    @classmethod
    def derancotor_4(slc, func):
        def inner(self, *args, **kwargs):
            print('开始装饰4')
            func(self, *args, **kwargs)
            print('结束装饰4')
        return inner

c = TestDeracotorClasss()

class Student:

    @c.deracotor_1 # 使用类中的实例方法装饰
    def test_1(self):
        print('我是测试1')

    @TestDeracotorClasss.derancotor_2
    def test_2(self):
        print('我是测试2')

    @TestDeracotorClasss.derancotor_3
    def test_3(self):
        print('我是测试3')
        
    @TestDeracotorClasss.derancotor_4
    def test_4(self):
        print('我是测试4')

s = Student()
s.test_1()
s.test_2()
s.test_3()
s.test_4()

## 输出结果
# 装饰1开始
# 我是测试1
# 装饰1结束
# --------------------------
# 装饰2开启
# 我是测试2
# 装饰2关闭
# --------------------------
# 开始装饰3
# 我是测试3
# 结束装饰3
# --------------------------
# 开始装饰4
# 我是测试4
# 结束装饰4

四 类作为装饰器

无参装饰器,被修饰的是普通函数
from functools import wraps

class animal:
    def __call__(self, func):
        @wraps(func)
        def wrapped_function(*args, **kwargs):
            return func(*args, **kwargs)
        return wrapped_function

@animal()       
def test(name, kind):
    print(f'{name} belongs to {kind}')

A = test('cow','mammals')
print(test.__name__)

## 输出结果
# cow belongs to mammals
# test
无参装饰器,被修饰的是类
class animal:
    def __init__(self, func):
        self.func = func
        print(self.func)
    
    def __call__(self, *args, **kwds):
        return self.func(*args, **kwds)

@animal
class cat:

    def test_1(self):
        print('running')

c = cat()
c.test_1()

## 输出结果
# <class '__main__.cat'>
# running
无参装饰器,被修饰的是类中的方法
class animal:
    def __init__(self, func):
        self.func = func
        print(self.func)
    
    def __call__(self, *args, **kwds):
        return self.func(self, *args, **kwds)


class cat:

    @animal
    def test_1(self):
        print('running')

c = cat()
c.test_1()

## 输出结果
# <function cat.test_1 at 0x000001AF56C00820>
# running
有参装饰器,被修饰的是普通函数
from functools import wraps


class animal:
    def __init__(self, *args, **kwargs):
        print('获取参数')
        print(args)
        print(kwargs)

    def __call__(self, func):
        @wraps(func)
        def wrapped_function(*args, **kwargs):
            print('working here')
            return func(*args, **kwargs)
        return wrapped_function

@animal(is_true=True)       
def test(name, kind):
    word = f'{name} belongs to {kind}'
    return word

A = test('cow','mammals')
print(test.__name__)

## 输出结果
# 获取参数
# ()
# {'is_true': True}
# working here
# test
有参装饰器,被修饰的是类
from functools import wraps

class animal:
    def __init__(self, *args, **kwargs):
        print('获取参数')
        print(args)
        print(kwargs)
    
    def __call__(self, func):
        @wraps(func)
        def inner(*args, **kwds):
            return func(*args, **kwds) 
        return inner

@animal(is_true=True)
class cat:

    def test_1(self):
        print('running')

c = cat()
c.test_1()
print(c.test_1.__name__)
## 输出结果
# 获取参数
# ()
# {'is_true': True}
# running
# test_1
有参装饰器,被修饰的是类中的方法
class animal:
    def __init__(self, *args, **kwargs):
        print('获取参数')
        print(args)
        print(kwargs)
    
    def __call__(self, func):
        
        def inner(*args, **kwds):
            return func(*args, **kwds) 
        return inner

class cat:

    @animal(is_true=True)
    def test_1(self):
        print('running')

c = cat()
c.test_1()

## 输出结果
# 获取参数
# ()
# {'is_true': True}
# running
  • 3
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 4
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值