.Tang

  博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

property:    -- 将装饰过的函数(方法)变成类属性,这样的属性需要通过  -  @函数(方法).setter 才能够直接修改这个属性

class A:
    @property                              # 将fun函数变成了类的属性
    def fun(self):    # 这儿只能有self参数
        return self._a
@fun.setter # 这个属性需要被setter才能直接修改属性值 def fun(self, n): self._a = n

 staticmethod: 将类的方法变成静态方法  -- 将类中的函数参数self 变成普通参数

应用场景:当把一个模块导入时,需要用到模块中的某个类和某个函数  from module import cls, fun   这样使用比较繁琐

可以将fun写进cls类中,加上staticmethod装饰器,就能通过cls.fun(argv) 调用,而又不会影响fun的功能

class A:
    @staticmethod
    def fun(self):   # 这儿self不在是实例化属性,变成普通参数了
        print(self)

a = A()
a.fun(2)   # 2被self接收

classmethod: 类装饰器   -- 将类本身当作参数传入函数中

class B:
    @classmethod
    def fun(cls):      # cls = B本身
        pass              

 

自己构建的装饰器

import functools


def log(fn):
    @functools.wraps(fn)    # 将fn的相关属性复制到wrap
    def wrap(*args, **kwargs):
        print(f"decorator {fn}")
        return fn(*args, **kwargs)
    print(f"wrap: {id(wrap)}")
    print(f"fn: {id(fn)}")
    return wrap

@log
def guai(x: int, y: int):
    print(x + y)

guai(1,5)

>>>
wrap: 4328403560
fn: 4328403424
decorator <function guai at 0x101fe31e0>
6

 

 

类型装饰器

def log(cls):
    class wraper:
        def __init__(self, *args, **kwargs):
            self.__dict__['inst'] = cls(*args, **kwargs)def __getattr__(self, item):
            print('here')
            print(item)
            return getattr(self.inst, item)
        def __setattr__(self, key, value):  # 拦截x.a的复制操作
            print('k:v', key, value)
            setattr(self.inst, key, value)   #拦截后储存到self.inst, 那么查询x.a也只能在self.inst中查到(通过__getattr__)
    return wraper

@log
class X: pass


x = X()
x.a = 100
print(x.__dict__)
print(x.a)

>>>
k:v a 100
{'inst': <__main__.X object at 0x10cd704a8>}
here
a
100

 

装饰器的应用场景:辅助开发工具(调用跟踪,性能测试,内存检测等任务),类可以实现单例模式

简单的统计调用次数:

def log(fn):
    def counter(*args, **kwargs):
        counter.__count__ += 1
        return fn(*args, **kwargs)

    counter.__count__ = 0
    return counter

@log
def run():pass


for i in range(4):
    run()
print(f"调用次数{run.__count__}")
>>>
调用次数4

 

属性管理:为目标添加额外的属性

def add_somethings(cls):
    cls.something = 1
    cls.something1 = lambda x: [1,2,3,]
    return cls


@add_somethings
class A: pass


print(A().something)
print(A().something1())

>>>
1
[1, 2, 3]

 

posted on 2018-03-26 19:53  .Tang  阅读(132)  评论(0编辑  收藏  举报