我们知道对于一个普通的类,我们要使用其中的函数的话,需要对类进行实例化,而一个类中,某个函数前面加上了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)