python-装饰器

2021/4/13 20:28:45

本文主要是介绍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')

    @classmethod
    def intro3(cls):
        print('there is a %s'%(cls.name))


    @property
    def intro4(self):
        print('there is a %s eating'%(self.name))

    @intro4.setter
    def intro5(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()
    a.intro4
    a.intro5=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)

 



这篇关于python-装饰器的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!


扫一扫关注最新编程教程