python中的装饰器的作用还是非常大的,可以去除冗余代码,简化开发;
# 传统写法,每一个方法都调用了logging方法来做日志的收集,冗余,改起来还麻烦;
class TestDecorator:
def print_title(self):
logging();
print("hello 我是title");
def print_url(self):
logging();
print("hello 我是url");
def logging():
import inspect
# python内置的inspect.stack方法可以将你引用的模块文件信息保留在里面,返回的是一个数据的数据形式
method_name = inspect.stack()[1][3];
print("Logger-info 进入方法 = {}".format(method_name))
def main():
decorator = TestDecorator();
decorator.print_title();
decorator.print_url();
if __name__ == '__main__':
main();
利用装饰器来进行日志的收集,和springboot的面向切面编程意思差不多
# 此时使用了@装饰器名称 的形式 在需要包装的地方进行了包装处理
class TestDecorator:
# 定义一个装饰器,接受操作函数,由python提供;
def logging(func):
def wrapper(*args, **kwargs):
# func.__name__ 获取包装函数名称;
print("LOGGING-INFO 进入 {} 方法".format(func.__name__));
# 继续调用被包装函数的调用;
return func(*args, **kwargs);
return wrapper;
@logging
def print_title(self):
print("hello 我是title");
@logging
def print_url(self):
print("hello 我是url");
def main():
decorator = TestDecorator();
decorator.print_title();
decorator.print_url();
if __name__ == '__main__':
main();
可传递参数的装饰器
class TestDecorator:
# 给装饰器一个默认值
def logging(level = "INFO"):
def wrapper(func):
def inner_wrapper(*args, **kwargs):
# func.__name__ 获取包装函数名称;
print("LOGGING-{} 进入 {} 方法".format(level,func.__name__));
# 继续调用被包装函数的调用;
return func(*args, **kwargs);
return inner_wrapper;
return wrapper;
@logging()
def print_title(self):
print("hello 我是title");
@logging()
def print_url(self):
print("hello 我是url");
def main():
decorator = TestDecorator();
decorator.print_title();
decorator.print_url();
if __name__ == '__main__':
main();
python类装饰器
# 类装饰器
class TestLogging:
def __init__(self,level = 'info'):
self.level = level;
def __call__(self, func):
def inner_wrapper(*args, **kwargs):
# func.__name__ 获取包装函数名称;
print("LOGGING-{} 进入 {} 方法".format(self.level, func.__name__));
# 继续调用被包装函数的调用;
return func(*args, **kwargs);
return inner_wrapper;
class TestDecorator:
@TestLogging("DEBUG")
def print_title(self):
print("hello 我是title");
@TestLogging()
def print_url(self):
print("hello 我是url");
def main():
decorator = TestDecorator();
decorator.print_title();
decorator.print_url();
if __name__ == '__main__':
main();
wrapt模块,这个是第三方模块,不是python内置的,需要自己下载一下
1.pip install wrapt
2.自己百度去查下用你的编辑器如何下载
未接受参数装饰器
import wrapt
# 使用warpt模块自动封装 没接受参数
@wrapt.decorator
# 类装饰器 实现不接受参数的装饰器
def logging(wrapped,instance,args,kwargs):
print("LOGGING-INFO 进入 {} 的方法".format(wrapped.__name__));
class TestDecorator:
@logging
def print_title(self):
print("hello 我是title");
@logging
def print_url(self):
print("hello 我是url");
def main():
decorator = TestDecorator();
decorator.print_title();
decorator.print_url();
if __name__ == '__main__':
main();
接受参数装饰器
import wrapt
# 类装饰器 接受参数的装饰器
def logging(level = "AoLiGei"):
# 使用warpt模块自动封装 接受参数
@wrapt.decorator
def logging_wrapper(wrapped,instance,args,kwargs):
print("LOGGING-{} 进入 {} 的方法".format(level,wrapped.__name__));
return wrapped(*args,**kwargs);
return logging_wrapper
class TestDecorator:
@logging("DEBUG")
def print_title(self):
print("hello 我是title");
@logging()
def print_url(self):
print("hello 我是url");
def main():
decorator = TestDecorator();
decorator.print_title();
decorator.print_url();
if __name__ == '__main__':
main();
python中的内置装饰器
1.python的静态方法,python没有像Java一样明确的定义静态方法,但是提供了内置装饰器@staticmethod来支持
class Message:
title = "我是静态属性";
@staticmethod
def get_info():
return "我是静态方法";
def main():
print("静态属性 = {},静态方法 = {}".format(Message.title,Message.get_info()));
if __name__ == '__main__':
main();
2.类方法 使用@classmethod 主要功能在于弥补构造方法缺陷,因为python中的构造方法只可以构造一个;
class TestClassMethod:
@classmethod
def get_info(cls):
print(cls);
def main():
TestClassMethod.get_info();
if __name__ == '__main__':
main();
当构造方法不足的时候,使用类方法弥补
class Message:
def __init__(self,title,url):
self.title = title;
self.url = url;
def __str__(self):
return "title = {},url = {}".format(self.title,self.url);
@classmethod
def get_instance(cls,info):
result = info.split("-");
return cls(result[0],result[1]);
def main():
msg_a = Message("1","2");
print(msg_a);
msg_b = Message.get_instance("1-2");
print(msg_b)
if __name__ == '__main__':
main();
3.属性访问
class Message:
def __init__(self,info):
self._info = info;
@property
def info(self):
return self._info;
@info.setter
def info(self,info):
self._info = info;
@info.deleter
def info(self):
del self._info;
def main():
msg = Message("aoligei");
# 调用了setter方法修改属性;
msg.info = "111"
# 直接访问属性,访问的就是info()方法;
print(msg.info);
del msg.info;
# 执行了del之后这里会报错;
print(msg.info);
if __name__ == '__main__':
main();