Python装饰器abstractmethod、property、classmethod、staticmethod及自定义装饰器

简介: 总览:@abstractmethod:抽象方法,含abstractmethod方法的类不能实例化,继承了含abstractmethod方法的子类必须复写所有abstractmethod装饰的方法,未被装饰的可以不重写@ property:方法伪装属性,方法返回值及属性值,被装饰方法不能有参数,...

总览:

@abstractmethod:抽象方法,含abstractmethod方法的类不能实例化,继承了含abstractmethod方法的子类必须复写所有abstractmethod装饰的方法,未被装饰的可以不重写

@ property:方法伪装属性,方法返回值及属性值,被装饰方法不能有参数,必须实例化后调用,类不能调用

@ classmethod:类方法,可以通过实例对象和类对象调用,被该函数修饰的方法第一个参数代表类本身常用cls,被修饰函数内可调用类属性,不能调用实例属性

@staticmethod:静态方法,可以通过实例对象和类对象调用,被装饰函数可无参数,被装饰函数内部通过类名.属性引用类属性或类方法,不能引用实例属性

案例讲解:


@abstractmethod

用于程序接口的控制,正如上面的特性,含有@abstractmethod修饰的父类不能实例化,但是继承的子类必须实现@abstractmethod装饰的方法

 

# -*- coding:utf-8 -*-


from abc import ABC, abstractmethod


class A(ABC):

    @abstractmethod
    def test(self):
        pass


class B(A):

    def test_1(self):
        print("未覆盖父类abstractmethod")


class C(A):

    def test(self):
        print("覆盖父类abstractmethod")


if __name__ == '__main__':
    a = A()
    b = B()
    c = C()
前两个分别报错如下:
    a = A()
TypeError: Can't instantiate abstract class A with abstract methods test

    b = B()
TypeError: Can'
t instantiate abstract class B with abstract methods test
第三个实例化是正确的

 

@ property

将一个方法伪装成属性,被修饰的特性方法,内部可以实现处理逻辑,但对外提供统一的调用方式,实现一个实例属性的get,set,delete三种方法的内部逻辑,具体含义看示例code。

 

# -*- coding:utf-8 -*-


# -*- coding:utf-8 -*-

class Data:
    def __init__(self):
        self.number = 123

    @property
    def operation(self):
        return self.number

    @operation.setter
    def operation(self, number):
        self.number = number

    @operation.deleter
    def operation(self):
        del self.number



@ classmethod,staticmethod

类方法classmethod和静态方法staticmethod是为类操作准备,是将类的实例化和其方法解耦,可以在不实例化的前提下调用某些类方法。两者的区别可以这么理解:类方法是将类本身作为操作对象,而静态方法是独立于类的一个单独函数,只是寄存在一个类名下。类方法可以用过类属性的一些初始化操作。

 

# -*- coding:utf-8 -*-


class Test:
    num = "aaaa"

    def __init__(self):
        self.number = 123

    @classmethod
    def a(cls, n):
        cls.num = n
        print(cls.num)

    @classmethod
    def b(cls, n):
        cls.a(n)

    @classmethod
    def c(cls, n):
        cls.number = n

    @staticmethod
    def d(n):
        Test.b(n)

分别通过类对象、实例化对象来调用

 


装饰器函数机制

谈装饰器的原理就不得不先理解Python的闭包,在函数内部再定义一个函数,并且这个函数用到了外边函数的变量,那么将这个函数以及用到的一些变量称之为闭包即内部函数对外部函数作用域里变量的引用(非全局变量),则称内部函数为闭包。

装饰器是建立在闭包的基础上,将被装饰函数传入闭包函数中执行则形成了装饰器。

闭包:

# -*- coding:utf-8 -*-


def test(a):

    def add(a):
        print(a+2)
    return add(a)


if __name__ == '__main__':
    test(2)

2


装饰器原型:

# -*- coding:utf-8 -*-


def B(fn):
    def b():
        return fn()+3
    return b


@B
def add():
    return 3


if __name__ == '__main__':
    str = fn()
    print(str)
----------------
6


当被装饰函数带参数:

# -*- coding:utf-8 -*-


def B(fn):
    def b(*args, **kwargs):
        return str(fn(*args, **kwargs))+"装饰"
    return b


@B
def fn(*args, **kwargs):
    num = 0
    for i in args:
        num +=i
    for i in kwargs.values():
        num += i
    return num


if __name__ == '__main__':
    num = fn(123, a=4, b=5)
    print(num)
----------------
15装饰


当装饰函数带额外参数,应该在装饰函数外再包裹一层函数

# -*- coding:utf-8 -*-


def A(n):
    def B(fn):
        def b(*args, **kwargs):
            return n+str(fn(*args, **kwargs))+"装饰"
        return b
    return B


@A("包裹前缀")
def fn(*args, **kwargs):
    num = 0
    for i in args:
        num +=i
    for i in kwargs.values():
        num += i
    return num


if __name__ == '__main__':
    num = fn(123, a=4, b=5)
    print(num)



----------------
包裹前缀15装饰


当多个装饰函数装饰一个函数时的执行顺序

# -*- coding:utf-8 -*-


def A(fn):

    print(1)

    def run():
        print(2)
        fn()
    print('a')
    return run


def B(fn):
    print(3)

    def run():
        print(4)
        fn()

    print('b')
    return run


def C(fn):
    print(5)

    def run():
        print(6)
        fn()

    print('c')
    return run

@A
@B
@C
def test():
    print(7)


if __name__ == '__main__':
    test()




----------------
5
c
3
b
1
a
2
4
6
7


由此可以得出多装饰情况下的运行情况:初始化运行从下到上,内部执行顺序从内到外。因为开始执行时会按照装饰顺序,组装成一个函数,而这个函数从最外层的return执行到最内层,故有上述顺序,就像剥洋葱一样。


类装饰器

# -*- coding:utf-8 -*-


class Add:

    def __init__(self, fn):
        print("初始化")
        self.num = 44
        self.fn = fn

    def __call__(self, *args, **kwargs):
        print("类装饰器开始工作")
        return self.fn(self.num)


@Add
def test(n):
    return 4+n


if __name__ == '__main__':
    num = test()
    print(num)
----------------
初始化
类装饰器开始工作
48


类装饰器使用地方较少,核心是通过复写类的回调方法__call__.


装饰器应用场景

  1. 引入日志

  2. 函数执行时间统计

  3. 执行函数前预备处理

  4. 执行函数后清理功能

  5. 权限校验等场景

  6. 缓存

相关文章
|
26天前
|
数据挖掘 数据处理 开发者
Python3 自定义排序详解:方法与示例
Python的排序功能强大且灵活,主要通过`sorted()`函数和列表的`sort()`方法实现。两者均支持`key`参数自定义排序规则。本文详细介绍了基础排序、按字符串长度或元组元素排序、降序排序、多条件排序及使用`lambda`表达式和`functools.cmp_to_key`进行复杂排序。通过示例展示了如何对简单数据类型、字典、类对象及复杂数据结构(如列车信息)进行排序。掌握这些技巧可以显著提升数据处理能力,为编程提供更强大的支持。
32 10
|
1月前
|
设计模式 前端开发 Shell
Python装饰器是什么?
装饰器是Python中用于动态修改函数、方法或类功能的工具,无需改变原代码。通过将函数作为参数传递并返回新函数,装饰器可以在原函数执行前后添加额外逻辑。例如,使用`@logger`装饰器可以打印函数调用日志,而`@timethis`则可用于计算函数执行时间。为了保持被装饰函数的元信息(如`__name__`和`__doc__`),可使用`functools.wraps`装饰器。此外,带参数的装饰器可通过嵌套函数实现,如`@timeitS(2)`,以根据参数条件输出特定信息。
90 59
|
1月前
|
测试技术 数据库 Python
Python装饰器实战:打造高效性能计时工具
在数据分析中,处理大规模数据时,分析代码性能至关重要。本文介绍如何使用Python装饰器实现性能计时工具,在不改变现有代码的基础上,方便快速地测试函数执行时间。该方法具有侵入性小、复用性强、灵活度高等优点,有助于快速发现性能瓶颈并优化代码。通过设置循环次数参数,可以更准确地评估函数的平均执行时间,提升开发效率。
106 61
Python装饰器实战:打造高效性能计时工具
|
2月前
|
缓存 数据安全/隐私保护 Python
python装饰器底层原理
Python装饰器是一个强大的工具,可以在不修改原始函数代码的情况下,动态地增加功能。理解装饰器的底层原理,包括函数是对象、闭包和高阶函数,可以帮助我们更好地使用和编写装饰器。无论是用于日志记录、权限验证还是缓存,装饰器都可以显著提高代码的可维护性和复用性。
49 5
|
2月前
|
存储 缓存 Python
Python中的装饰器深度解析与实践
在Python的世界里,装饰器如同一位神秘的魔法师,它拥有改变函数行为的能力。本文将揭开装饰器的神秘面纱,通过直观的代码示例,引导你理解其工作原理,并掌握如何在实际项目中灵活运用这一强大的工具。从基础到进阶,我们将一起探索装饰器的魅力所在。
|
2月前
|
Python
探索Python中的装饰器:简化代码,增强功能
在Python的世界里,装饰器就像是给函数穿上了一件神奇的外套,让它们拥有了超能力。本文将通过浅显易懂的语言和生动的比喻,带你了解装饰器的基本概念、使用方法以及它们如何让你的代码变得更加简洁高效。让我们一起揭开装饰器的神秘面纱,看看它是如何在不改变函数核心逻辑的情况下,为函数增添新功能的吧!
|
2月前
|
测试技术 开发者 Python
探索Python中的装饰器:从入门到实践
装饰器,在Python中是一块强大的语法糖,它允许我们在不修改原函数代码的情况下增加额外的功能。本文将通过简单易懂的语言和实例,带你一步步了解装饰器的基本概念、使用方法以及如何自定义装饰器。我们还将探讨装饰器在实战中的应用,让你能够在实际编程中灵活运用这一技术。
50 7
|
2月前
|
程序员 测试技术 数据安全/隐私保护
深入理解Python装饰器:提升代码重用与可读性
本文旨在为中高级Python开发者提供一份关于装饰器的深度解析。通过探讨装饰器的基本原理、类型以及在实际项目中的应用案例,帮助读者更好地理解并运用这一强大的语言特性。不同于常规摘要,本文将以一个实际的软件开发场景引入,逐步揭示装饰器如何优化代码结构,提高开发效率和代码质量。
74 6
|
2月前
|
开发者 Python
Python中的装饰器:从入门到实践
本文将深入探讨Python的装饰器,这一强大工具允许开发者在不修改现有函数代码的情况下增加额外的功能。我们将通过实例学习如何创建和应用装饰器,并探索它们背后的原理和高级用法。
55 5
|
3月前
|
设计模式 缓存 开发者
Python中的装饰器:从入门到实践####
本文深入探讨了Python中强大的元编程工具——装饰器,它能够以简洁优雅的方式扩展函数或方法的功能。通过具体实例和逐步解析,文章不仅介绍了装饰器的基本原理、常见用法及高级应用,还揭示了其背后的设计理念与实现机制,旨在帮助读者从理论到实战全面掌握这一技术,提升代码的可读性、可维护性和复用性。 ####

热门文章

最新文章

推荐镜像

更多