一个几个人做网站的几个故事电影,深圳企业网站建设费用明细,贵阳专业做网站公司有哪些,wordpress面包屑导航不要子分类Python学习之——装饰器 参考基础闭包概念装饰器系统自带的装饰器propertystaticmethodclassmethod 自定义装饰器函数的装饰器无参数有参数 类的装饰器无参数有参数 functools.wraps装饰器类 装饰器实现单例模式 参考
python装饰器的4种类型#xff1a;函数装饰函数、函数装饰… Python学习之——装饰器 参考基础闭包概念装饰器系统自带的装饰器propertystaticmethodclassmethod 自定义装饰器函数的装饰器无参数有参数 类的装饰器无参数有参数 functools.wraps装饰器类 装饰器实现单例模式 参考
python装饰器的4种类型函数装饰函数、函数装饰类、类装饰函数、类装饰类 9.4 定义一个带参数的装饰器
基础
闭包概念
Python闭包Closure详解
闭包概念在一个内部函数中对外部作用域的变量进行引用并且外部函数的返回值为内部函数那么内部函数就叫做闭包。
示例
def outer_func(year):def inner_func(month):print(fyear:{year}, month:{month})return inner_funcclosure_func outer_func(2023)
closure_func (12)调用func时产生了闭包inner_func其持有外层函数的自由变量year当函数func的生命周期结束之后year这个变量依然存在因为它被闭包引用了不会被回收。
闭包的特点: 内部函数可以读取外层函数内的局部变量并让其常驻内存不会被回收所以注意内存泄漏
装饰器
一文搞懂什么是Python装饰器
装饰器是用来增强函数/类功能的一个函数
import loggingdef no_arg_decorator(func):call_count 0def inner_func(*arg, **kwargs):# do somethings, examplenonlocal call_countcall_count 1print(fcall {func.__name__} func, total call count:{call_count })func(*arg, **kwargs)return inner_funcdef arg_decorator(*outer_arg, **outer_kwargs):def inner_func(func):def inner_func2(*arg, **kwargs):# do somethings use outer_arg, outer_kwargs, examplefile_path outer_kwargs.get(log_file_path)if file_path:logging.basicConfig(filenamefile_path,format%(asctime)s - %(name)s - %(levelname)s - %(message)s-%(funcName)s,levellogging.DEBUG)logging.debug(fdebug, call {func.__name__}, arg:{arg}, kwargs:{kwargs})func(*arg, **kwargs)return inner_func2return inner_funcdef test_func1(a1):pass# 1.不用语法糖符号
# 1.1 无参装饰器
wraped_func1 no_arg_decorator(test_func1)# 1.2 有参装饰器
wraped_func2 arg_decorator(log_file_pathlog.txt)(test_func1)# 2.采用语法糖符号
# 2.1 无参装饰器
no_arg_decorator
def test_func2(a1):pass# 2.2 有参装饰器
arg_decorator(log_file_pathlog.txt)
def test_func3(a1):passif __name__ __main__:print()wraped_func1()wraped_func1()wraped_func2(a11)test_func2()test_func3(a111)# 结果call test_func1 func, total call count:1
call test_func1 func, total call count:2
call test_func2 func, total call count:1系统自带的装饰器
property
Python 中 property() 函数及 property 装饰器
class Food(object):def __init__(self):self._price 0propertydef price(self):return self._price price.setterdef price(self, value):if value 0:raise ValueError(price must large than 0!)self._price valueprice.deleterdef price(self):del self._price
staticmethod
staticmethod修饰过的方法叫静态方法可以直接通过类调用方法这样做的好处是执行效率比较高也可以通过实例调用该方法。
from datetime import datetimeTIME_FORMAT_STR %Y/%m/%d/ %H:%M:%Sclass TimeUtil():staticmethoddef timestamp_to_utc_str(timestamp: float, format_strTIME_FORMAT_STR) - str:时间戳转utc-0时区的时间datetime_obj: datetime datetime.utcfromtimestamp(timestamp)return datetime_obj.strftime(format_str)staticmethoddef timestamp_to_local_str(timestamp: float, format_strTIME_FORMAT_STR) - str:时间戳转当前本地时区的时间datetime_obj: datetime datetime.fromtimestamp(timestamp)return datetime_obj.strftime(format_str)
classmethod
classmethod修饰过的方法叫类方法可以直接通过类或者实例调用方法
利用classmethod实现单例模式
from datetime import datetimeclass SingletonBase(object):__instance Noneclassmethoddef get_instance(cls, *arg, **kwargs):if cls.__instance is None:cls.__instance cls()cls.__instance.init(*arg, **kwargs)return cls.__instancedef init(self, *arg, **kwargs):passclass TestMgr(SingletonBase):def init(self, *arg, **kwargs):print(fI am TestMgr Singleton, arg:{arg}, kwargs:{kwargs})if __name__ __main__:test_mgr TestMgr.get_instance(hello, world, timedatetime.now().strftime(%Y/%m/%d/ %H:%M:%S))自定义装饰器
python装饰器2类装饰器 python装饰器的4种类型函数装饰函数、函数装饰类、类装饰函数、类装饰类
函数的装饰器
无参数
import timeall_func {}# 用于函数注册的装饰器
def register_func(func):all_func[func.__name__] funcreturn func# 用于统计函数耗时的装饰器
def calc_time(func):def inner_func():start time.time()func()end time.time()print(fcall {func.__name__} func, cost time:{int(end - start)} second)return inner_funccalc_time
def test_func4():time.sleep(2)if __name__ __main__:print()test_func4()# 结果call test_func4 func, cost time:2 second有参数
# -*- coding:utf-8 -*-
from functools import wrapstest_dict {}def Decorator(arg10, arg21):def inner_func(func):funcName func.__name__test_dict[funcName] func# 没有return func则该装饰器默认返回None会导致被Decorator装饰后的函数无法被调用# 有return func则被Decorator装饰后的函数还是被赋值为原函数后续还可以调用# return funcreturn inner_funcdef decorator(*arg):return Decorator(*arg)def Decorator2(arg10, arg21):def inner_func(func):wraps(func)def wrapper(*args, **kwargs):# do somethingreturn func(*args, **kwargs)funcName func.__name__test_dict[funcName] func# 有return wrapper则被Decorator2装饰后的函数还是被赋值为原函数后续还可以调用return wrapperreturn inner_funcdef decorator2(*arg):return Decorator2(*arg)Decorator()
def test_func_a():passdecorator()
def test_func_b():passDecorator2()
def test_func_c():passdecorator2()
def test_func_d():passif __name__ __main__:print(test_dict)# 结果
{test_func_a: function test_func_a at 0x000001F7B6851D00, test_func_b: function test_func_b at 0x000001F7B6851DA0, test_func_c: function test_func_c at 0x000001F7B6851E40, test_func_d: function test_func_d at 0x000001F7B6851F80}类的装饰器
无参数
# decorator1(cls)返回一个函数inner_func的写法
def decorator1(cls):def inner_func(a):print(class name:, cls.__name__)return cls(a)return inner_func# decorator2(cls)返回一个类inner_cls的写法
def decorator2(cls):class inner_cls:def __init__(self, *args, **kwargs):self.wrapped_obj cls(*args, **kwargs)def __getattr__(self, name):return getattr(self.wrapped_obj, name)return inner_clsdecorator1
class FooClass1():def __init__(self, a):self.a adef fun(self):print(self.a , self.a)decorator2
class FooClass2():def __init__(self, a):self.a adef fun(self):print(self.a , self.a)foo1 FooClass1(Foo1_a)
foo1.fun()foo2 FooClass2(Foo2_a)
foo2.fun()
有参数
1.通过装饰器实现子类的自动注册
all_subcls {}def register_subcls(base_cls_name):def decorate(sub_cls):if base_cls_name not in all_subcls :all_subcls[base_cls_name] {}all_subcls[base_cls_name][sub_cls.__name__] sub_clsreturn decoratedef get_subcls(base_cls_name, sub_cls_name):if base_cls_name not in all_subcls:return Noneelse:return all_subcls[base_cls_name].get(sub_cls_name)# 使用
class TestBase1(object):staticmethoddef create_instance(sub_cls_name, *args, **kwargs):sub_cls get_subcls(TestBase1, sub_cls_name)return sub_cls(*args, **kwargs) if sub_cls else Nonedef __init__(self, *args, **kwargs):self.args argsself.kwargs kwargsdef print_self(self):print(fTestBase1, args:{args}, kwargs:{kwargs})register_subcls(TestBase1)
class TestA(TestBase1):def print_self(self):print(fTestA, args:{args}, kwargs:{kwargs})register_subcls(TestBase1)
class TestB(TestBase1):def print_self(self):print(fTestB, args:{args}, kwargs:{kwargs})通过装饰器给类增加静态函数/类函数/成员函数
# 实例方法
def add_instance_method(cls):def inner_func(func):setattr(cls, func.__name__, func)return inner_func# 类方法
def add_class_method(cls):def inner_func(func):setattr(cls, func.__name__, classmethod(func))return inner_func# 静态方法
def add_static_method(cls):def inner_func(func):setattr(cls, func.__name__, staticmethod(func))return inner_funcdef add_func_decorator(cls):add_instance_method(cls)def test_instance_func(self):print(test_instance_func)add_class_method(cls)def test_class_func(cls):print(test_class_func)add_static_method(cls)def test_static_func():print(test_static_func)return clsadd_func_decorator
class TestClass():def __init__(self):passif __name__ __main__:TestClass.test_class_func()TestClass.test_static_func()test_obj TestClass()test_obj.test_instance_func()# 结果
test_class_func
test_static_func
test_instance_funcfunctools.wraps
functools.wraps对我们的装饰器函数进行了装饰之后消除了装饰器对原函数的影响。 具体Python装饰器深度解析
装饰器类
之前都是用函数来构造装饰器其实类也可以用来构建装饰器 装饰器类 先熟悉一下Python __call__()方法 Python 中凡是可以将 () 直接应用到自身并执行都称为可调用对象。可调用对象包括自定义的函数、Python 内置函数以及本节所讲的类实例对象。 __ call__()方法的功能类似于在类中重载 () 运算符使得类实例对象可以像调用普通函数那样以“对象名()”的形式使用。 from functools import wrapsclass logit(object):def __init__(self, logfileout.log):self.logfile logfiledef __call__(self, func):wraps(func)def wrapped_function(*args, **kwargs):log_string func.__name__ was calledprint(log_string)with open(self.logfile, a) as fp:fp.write(log_string \n)# 发送一个通知self.notify()return func(*args, **kwargs)return wrapped_functiondef notify(self):pass# 使用
logit()
def myfunc1():pass装饰器实现单例模式
Python单例模式(Singleton)的N种实现
1.使用函数装饰器实现单例
def Singleton(cls):_instance {}def inner():if cls not in _instance:_instance[cls] cls()return _instance[cls]return innerSingleton
class Cls(object):def __init__(self):passcls1 Cls()
cls2 Cls()
print(id(cls1) id(cls2))2.使用类装饰器实现单例
class Singleton(object):def __init__(self, cls):self._cls clsself._instance {}def __call__(self):if self._cls not in self._instance:self._instance[self._cls] self._cls()return self._instance[self._cls]Singleton
class Cls2(object):def __init__(self):passcls1 Cls2()
cls2 Cls2()
print(id(cls1) id(cls2))# 同时由于是面对对象的这里还可以这么用
class Cls3():passCls3 Singleton(Cls3)
cls3 Cls3()
cls4 Cls3()
print(id(cls3) id(cls4))