zoukankan      html  css  js  c++  java
  • python基础之内置装饰器

    装饰器

      简介

      功能与格式

      内置装饰器

        @classmethod

        @propertry

        @staticmethod

      其它

    ---------------------------------------------------------------------------------------------------------------------------------

    简        介

    python中的解释器是你进入python大门的一道坎,不管你跨不跨过去它都在那里.

    ///装饰器本质上是一个python函数,他可以让其他函数在不需要任何代码变动的前提下增加额外功能,装饰器的返回值也是一个函数对象.他经常用于有切面去求的场景,比如:插入日志,性能测试,事物处理,缓存,权限校验等场景,装饰器是结局这类问题的绝佳设计,有了装饰器,我们就可以抽离出大量与函数功能本身无关的雷同代码并继续重用////

    概括地说:装饰器的作用就是为已存在的函数或对象添加额外的功能

    功能和格式

    装饰器的主要功能:

    在不改变函数调用方式的基础上再函数的前,后添加功能

    装饰器的固定写法:

    def timer(func):
        def inner(*args,**kwargs):
            '''执行函数之前要做的'''
            re = func(*args,**kwargs)
            '''执行函数之后要做的'''
            return re
        return inner
    装饰器的固定格式
    from functools import wraps
    
    def deco(func):
        @wraps(func) #加在最内层函数正上方
        def wrapper(*args,**kwargs):
            return func(*args,**kwargs)
        return wrapper
    装饰器的固定格式-----wraps版

    @classmethod  装饰器

    本质上:一个方法不用对象属性但是使用静态属性-----类方法

    |||@classmethod,某一个方法被创造出来,就是为了进行静态变量进行操作,根本不涉及到对象,所以这个方法就是应该被定义成 ---类方法(@classmethod装饰) 调用这个方法可以使用对象调用,也可以使用类调用,但是这个方法的默认参数永远是当前的 命名空间,而不是对象的|||

    将self改成了cls

    class A:
        __count = 0   # 隐藏了count属性
        def __init__(self,name):
            self.name = name
            self.__add_count()  # 每一次实例化的时候调
                                # 用私有方法来对__count进行累加
        @classmethod
        def __add_count(cls):  # 定义一个私有的方法
            # print(cls,A)
            cls.__count += 1      # 让这个方法只能在类的内部被使用
    
        @classmethod  # 被classmethod装饰器装饰的方法,都有一个默认的参数,这个参数就是当前类
        def show_count(cls):   # 定义一个普通方法,
            # print(cls,A)
            return cls.__count    # 让用户可以从外部查看__count的值
    
        def eat(self):
            print('%s在吃饭'%self.name)
    print(A.show_count())
    a = A('lufei')
    print(alex.show_count())
    b= A('suolong')
    print(A.show_count())
    A.eat(a)
    
    
    #结果
    0
    1
    2
    alex在吃饭
    View Code

    @staticmethod 装饰器

    作用:调用时不用添加属性直接可以用

    class Student:
        def __init__(self):
            # self :属于这个学生自己的一块空间
            self.courses = []
    
        @staticmethod
        def show_courses():   # 不是查看已选课程,而是查看所有课程 -- 静态方法
            # 不是操作学生对象本身空间中的数据,而是所有的学生这个方法的结果都是一样的
            print('打开课程文件,一个一个读出来')
    
        def select_courses(self):              # 选课  是一个对象方法(普通的方法)
            self.courses.append('某一门课程')  # 操作的课程一定是属于某一个对象
    
    Student.show_courses()
    alex = Student()
    alex.show_courses()
                  普通的方法           类方法             静态方法
    默认参数        self                cls                无
    操作的变量      操作对象的属性     操作静态属性         既不操作对象属性,也不操作类的属性
    所属的命名空间   类                  类                 类
    调用方式        对象                类/对象             类/对象
    对应的装饰器     无                @classmethod        @staticmethod
    上面两个装饰器的比较

    ---用哪一个命名空间中的名字,就定义不同的方法:

    1)只要用self     就是普通方法    只能对象调

    2)只要用cls       就是类方法        可以用类可以用对象

    3)啥也不用        就是静态方法       可以用类可以用对象

    @property  装饰器

    作用:  把方法变成属性

    from math  import pi
    calss Circle:
        def __init__(self,r):
            self.r=r
        @property       #把一个方法伪装成属性,源代码有人写
        def area(self):
            return pi*self.r**2
    
    d = Circle(10)
    print(d.area)                  #把方法变成属性
    
    
    #结果
    314

    其       它

    1)最简单的装饰器

    def a(func):
        print(1)
            print(2)
            func()
            print(3)
        return b
    @a                                       
    def c():
        print(4)
    
    
    c()
    
    
    
    运行过程:
    先执行@a,得到一个1和函数的对象b, b和b()是不一样的,b只是一个对象,并不会运行,
    然后运行c()的时候,执行b参数,得到2,func()  得到4,3
    
    #结果:
    1,2,4,3
    View Code

    2)当加入参数的装饰器

    def a(func):
        print(1)
        def b(*args,**kwargs):
        print(2)
        func(*args,**kwargs)
        print(3)
        return b
    @a
    def c(a,b):
        print(a+b)
    c(3,4)
    
    
    运行过程:
    #args 将参数打包为tuple给函数使用(3,4)
    #kwargs 将参数打包为dict给函数使用,将传入的a=1这样的参数变成{'a':1}
    我们这里相当于a(c(a,b))这个函数
    所以这里的b()其实就就相当于c()
    
    
    
    
    #结果:
    1,2,7,3
    View Code
  • 相关阅读:
    不一样的图片加载方式
    赢 1000 元现金红包!助力奥运,猜金银牌数赢现金
    接入 SDK 结果翻车了?了解 SDK 的那些事
    关于 IPv6 国家有大动作啦!快来瞅瞅行动计划都说了什么~
    MySQL 那些常见的错误设计规范
    webpack 从 0 到 1 构建 vue
    PHP 网络通信底层原理分析
    内部方案汇总
    taro+vue3 引入 taro-ui-vue3
    springboot+tomcat+vue+nginx 前后端分离配置
  • 原文地址:https://www.cnblogs.com/tianshuai1/p/10139673.html
Copyright © 2011-2022 走看看