zoukankan      html  css  js  c++  java
  • python-三器 装饰器

    我们知道对于一个普通的类,我们要使用其中的函数的话,需要对类进行实例化,而一个类中,某个函数前面加上了staticmethod或者classmethod的话,那么这个函数就可以不通过实例化直接调用
    """
    @staticmethod不需要表示自身对象的self和自身类的cls参数。如果在@staticmethod中要调用到这个类的一些属性方法,直接类名.属性名或类名.方法名。
    @classmethod也不需要self参数,但第一个参数需要是表示自身类的cls参数。而@classmethod因为持有cls参数,可以来调用类的属性,类的方法,实例化对象等,避免硬编码。
    @property使方法像属性一样调用,就像是一种特殊的属性。有参函数时使用@name.setter
    @pysnooper日志打印工具,用显示函数间的入参和返回值的变化
    """
    class Animal(object):
        name = 'dog'
        def __init__(self,name):
            self.name = name
    
        def intro1(self):
            print('there is a %s'%(self.name))
    
        @staticmethod
        def intro2():
            print('there is a %s')
    
        @staticmethod
        def intro3(test):
            print('there is a %s'%(test))
    
        @classmethod
        def intro4(cls):
            print('there is a %s'%(cls.name))
    
        @classmethod
        def intro5(cls,test):   #传参
            cls.intro1(cls)     #调用类方法
            print('there is a %s %s'%(cls.name,test))
    
    
        @property
        def intro6(self):
            print('there is a %s eating'%(self.name))
    
        @intro6.setter
        def intro7(self,value):
            print('there is %d %s eating'%(value,self.name))
    
    
    import pysnooper
    @pysnooper.snoop()
    #@pysnooper.snoop('log.log')
    def lisy(a):
        return [x - 10 if x in [11, 12, 13] else x for x in a]
    
    
    if __name__ == '__main__':
        a = Animal('cat')
        a.intro1()
        Animal.intro2()
        Animal.intro3('test')
        Animal.intro4()
        Animal.intro5('test')
        a.intro6
        a.intro7=2
    
        lisy([1, 2, 3, 11, 12, 13, '111', 222])
    """
    1.修饰无参函数
    2.修饰有参函数
    3.不带参数的装饰器
    4.带参数的装饰器
    5.类装饰器
    """
    
    
    #修饰无参函数 ,无参数时不需要直接调用,在@log1时已经调用了
    def log1(func):
        func()
    @log1
    def test():
        print('test: log1')
    
    #修饰有参函数
    def log2(func):
        def inner(*args, **kwargs):
            func(*args, **kwargs)
        return inner
    @log2
    def test(num):
        print('testlog2:',num,test.__name__)
    test(20) #相当于log(test(20))
    
    
    
    from functools import wraps
    #@wraps可以保证装饰器修饰的函数的name的值保持不变
    
    #不带参数的装饰器
    def log3(func):
        @wraps(func)
        def inner(*args, **kwargs,):
            func(*args, **kwargs)
        return inner
    @log3
    def test(num):
        print('testlog3:',num,test.__name__)
    test(30) #相当于log(test(30))
    
    
    #带参数的装饰器
    def log4(level):
        def log(func):
            @wraps(func)
            def inner(*args, **kwargs,):
                if level == "warn":
                    print("%s is running" % func.__name__)
                func(*args, **kwargs)
            return inner
        return log
    @log4(level="warn")
    def test(num):
        print('testlog4:', num, test.__name__)
    test(40)
    
    
    #实现带参数和不带参数的装饰器自适应
    def log(arg):
        if callable(arg):  # 判断入参的参数是否有值,不带参数的装饰器调用这个分支
            def log3(func):
                @wraps(func)
                def inner(*args, **kwargs, ):
                    func(*args, **kwargs)
                return inner
            return log3
        else:
            def log4(func):
                @wraps(func)
                def inner(*args, **kwargs,):
                    if arg == "warn":
                        print("%s is running" % func.__name__)
                    func(*args, **kwargs)
                return inner
            return log4
    @log(arg=None)
    def test(num):
        print('testlog:', num, test.__name__)
    test(0)
    
    
    #修饰有参函数,返回入参出参
    def log5(func):
        def inner(*args, **kwargs):
            print('入参:',func.__name__, args, kwargs)
            res =func(*args, **kwargs)
            print('出参:',func.__name__, res)
            return res
        return inner
    @log5
    def test(num):
        print('testlog5:', num, test.__name__)
        return num
    test(50)
    
    
    # 类装饰器
    class Loging:
        def __init__(self, level):
            self.level = level
        def __call__(self, func):
            @wraps(func)
            def inner(*args, **kwargs):
                if self.level == "warn":
                    print("%s is running" % func.__name__)
                func(*args, **kwargs)
            return inner
    
    @Loging(level="warn")
    def test(num):
        print('testLoging:', num, test.__name__)
    test(0)
    
    
    class Log_class:
        def __init__(self, func):
            self.func = func
        def __call__(self, *args, **kwargs):
            print('初始化装饰器')
            self.func(*args, **kwargs)
            print('中止装饰器')
    @Log_class
    def test(num):
        print('testLog_class:', num)
    test(0)
  • 相关阅读:
    MFC 时钟 计算器 日期天数计算
    test10
    test9
    iOS 防止按钮快速点击造成多次响应的避免方法
    NSBundle读取图片 plist文件和txt文件
    按指定格式的子字符串,删除和分割字符串
    python批处理入门知识点
    命令行ffmpeg批量旋转视频
    NSData转化成十六进制字符串
    xcode里面使用Memory Leaks和Instruments检测内存泄漏
  • 原文地址:https://www.cnblogs.com/shuzf/p/14654537.html
Copyright © 2011-2022 走看看