zoukankan      html  css  js  c++  java
  • 装饰器/描述器/常用内置装饰器

    装饰器:

    给一个现有函数增加功能,保证参数的正确传递。

    以面向对象的方式封装:

    def add(x,y):
        print('Cala: %s +%s='%(x,y),end='')
        return x + y
    
    class MyCounter:
        def __init__(self,f):
            self.func=f
            self.count=0
        def __call__(self, *args, **kwargs):
            self.count+=1
            return self.func(*args,**kwargs)
    
    myadd=MyCounter(add)
    #myadd(1,2)
    print(myadd(1,2))

    以函数的方式封装:

    def add(x,y):
        print('Cala: %s +%s='%(x,y),end='')
        return x + y
    
    def my_counter(f):
        def wapper(*args,**kwargs):
            wapper.counter+=1
            return f(*args,**kwargs)
        wapper.counter=0
        return wapper
    
    
    myadd=my_counter(add)
    print(myadd(1,2))

    装饰器语法:

    def my_counter(f):
        def wapper(*args,**kwargs):
            wapper.counter+=1
            return f(*args,**kwargs)
        wapper.counter=0
        return wapper
    
    
    @my_counter
    def minus(x,y):
        print('Cals: %s-%s=' %(x,y),end='')
        return x-y
    
    print(minus(2,1),'	 counter:',minus.counter)
    print(minus(2,1),'	 counter:',minus.counter)
    print(minus(2,1),'	 counter:',minus.counter)
    
    @my_counter
    def add(x,y):
        print('Cala: %s +%s='%(x,y),end='')
        return x + y
    print(add(1,2),'	 counter:',add.counter)
    print(add(1,2),'	 counter:',add.counter)
    print(add(1,2),'	 counter:',add.counter)

    描述器

    将类属性作为对象,管理一个类属性的“访问”,“修改”,“删除”

    class MyAttribute:
        def __get__(self, instance, owner):
            print('get:',self,instance,owner)  #instance是实例,owner是类
        def __set__(self, instance, value):
            print('set:',self,instance,value)  #value 是赋的值
        def __delete__(self, instance):
            print('delete:',self,instance)
    
    class Myclass:
        attr=MyAttribute()
    
    mc=Myclass()
    print('xx')
    mc.attr
    mc.attr=1
    del mc.attr
    
    
    运行结构:
    xx
    get: <__main__.MyAttribute object at 0x10402ed30> <__main__.Myclass object at 0x10402eeb8> <class '__main__.Myclass'>
    set: <__main__.MyAttribute object at 0x10402ed30> <__main__.Myclass object at 0x10402eeb8> 1
    delete: <__main__.MyAttribute object at 0x10402ed30> <__main__.Myclass object at 0x10402eeb8>

    一个基于描述器的装饰器:

    class Property(object):
        def __init__(self,fget=None):
            self.fget=fget
        def __get__(self, obj,objtype=None):
            if obj is None:
                return  self
            if self.fget is None:
                raise  AttributeError("unreadable attribute")
            return  self.fget(obj)
    
    class Person():
        def __init__(self,name):
            self._name=name
            self.is_anonymous=False
    
        @Property
        def name(self):
            if not self.is_anonymous:
                return self._name
            else:
                return 'anonymous'
    
    p=Person('Tuple')
    print(p.name)
    p.is_anonymous=True
    print(p.name)

    常用的内置装饰器(property):就是把一个方法变成属性的样子

    class Person:
        def __init__(self,name):
            self._name=name
    
        @property
        def name(self):
            print("通过property来获取name")
            if hasattr(self,'_name'):
                return self._name
            else:
                raise AttributeError('没有name这个属性')
    
        @name.setter
        def name(self,value):
            print('通过property来设置name')
            self._name=value
    
        @name.deleter
        def name(self):
            print('通过propety来删除name')
            del self._name
  • 相关阅读:
    跟vczh看实例学编译原理——二:实现Tinymoe的词法分析
    跟vczh看实例学编译原理——一:Tinymoe的设计哲学
    跟vczh看实例学编译原理——零:序言
    2013年终总结
    如何设计一门语言(十二)——设计可扩展的类型
    开始用Word 2013来写博客
    如何设计一门语言(十一)——删减语言的功能
    如何设计一门语言(十)——正则表达式与领域特定语言(DSL)
    链表
    结构的学习
  • 原文地址:https://www.cnblogs.com/taoge188/p/8544570.html
Copyright © 2011-2022 走看看