Python基础第22天

一:描述符的应用

众所周知,python是弱类型语言,即参数的赋值没有类型限制,下面我们通过描述符机制来实现类型限制功能

class Typed:
    def __init__(self,key,expected_type):
        self.key=key
        self.expected_type=expected_type
    def __get__(self, instance, owner):
        print('get方法')
        # print('instance参数【%s】'%instance)
        # print('owner参数【%s】'%owner)
        return instance.__dict__[self.key]

    def __set__(self, instance, value):
        print('set方法')
        # print('instance参数【%s】'%instance)
        # print('value参数【%s】' % value)
        # print('====>',self)
        if not isinstance(value,self.expected_type):
            # print('你传入的类型不是字符串,错误')
            # return
            raise TabError('%s 你传入的类型不是%s'%(self.key,self.expected_type))
        instance.__dict__[self.key]=value
    def __delete__(self, instance):
        # print('delete方法')
        # print('instance参数【%s】' % instance)
        instance.__dict__.pop(self.key)
class People:
    name=Typed('name',str) #描述符
    age=Typed('name',int)
    def __init__(self,name,age,salary):
        self.name=name  #触发代理
        self.age=age
        self.salary=salary

p1=People(123,13,13.3)
print(p1.__dict__)
p1=People(123,18,13.3)
print(p1.__dict__)
p1.name
print(p1.name)

print(p1.__dict__)
p1.name='aaa'
print(p1.__dict__)

print(p1.__dict__)
del p1.name
print(p1.__dict__)

二:类的装饰器

def deco(func):
    print('============')
    return func

@deco   #test=deco(test)
def test():
    print('test函数运行')
test()


@deco   #语法糖修饰类  Foo=deco(Foo)
class Foo:
pass
============
test函数运行


============
 
def deco(obj):
    print('============',obj)
    obj.x=1
    obj.y=2
    obj.z=3
    return obj
@deco   #Foo=deco(Foo)
class Foo:
    pass
print(Foo.__dict__)


def deco(obj):
    print('============',obj)
    obj.x=1
    obj.y=2
    obj.z=3
    return obj
@deco   #Foo=deco(Foo)
def test():
    print('test函数运行')
test.x=1
test.y=1
print(test.__dict__)  #验证了一切皆对象
一切皆对象

类的装饰器修订版:   操作类属性

def Typed(**kwargs):
    def deco(obj):
        # print('--->',kwargs)
        # print('类名---》',obj)
        for key,val in kwargs.items():
            # obj.__dict__[key]=val
            setattr(obj,key,val)
        return obj
        print('==>',kwargs)
    return deco

@Typed(x=1,y=2,z=3)    #Typed(x=1,y=2,z=3)---->deco   @deco---->Foo=deco(Foo)
class Foo:
    pass
print(Foo.__dict__)

@Typed(name='egon')
class Bar:
    pass
print(Bar.name)  #egon
class Typed:
    def __init__(self,key,expected_type):
        self.key=key
        self.expected_type=expected_type
    def __get__(self, instance, owner):
        print('get方法')
        # print('instance参数【%s】'%instance)
        # print('owner参数【%s】'%owner)
        return instance.__dict__[self.key]

    def __set__(self, instance, value):
        print('set方法')
        # print('instance参数【%s】'%instance)
        # print('value参数【%s】' % value)
        # print('====>',self)
        if not isinstance(value,self.expected_type):
            # print('你传入的类型不是字符串,错误')
            # return
            raise TabError('%s 你传入的类型不是%s'%(self.key,self.expected_type))
        instance.__dict__[self.key]=value
    def __delete__(self, instance):
        # print('delete方法')
        # print('instance参数【%s】' % instance)
        instance.__dict__.pop(self.key)
def deco(**kwargs):  #kwargs={'name':str,'age':int}
    def wrapper(obj):   #obj=People
        for key,val in kwargs.items():  #(('name',str),('age',int))
            setattr(obj,key,Typed(key,val))  #People.name=Typed('name',str)
        return obj
    return wrapper
@deco(name=str,age=int)  #@wrapper====》People=wrapper(People)
class People:
    # name=Typed('name',str) #调用
    # age=Typed('age',int)
    def __init__(self,name,age,salary,gender,height):
        self.name=name
        self.age=age
        self.salary=salary

p1=People('yyy',13,13.3,'x','y')
print(People.__dict__)
类的装饰器的应用

描述符是可以实现大部分python类特性中的底层魔法,包括@classmethod,@staticmethd,@property甚至是__slots__属性

 

       利用描述符原理完成一个自定制@property,实现延迟计算(本质就是把一个函数属性利用装饰器原理做成一个描述符:类的属性字典中函数名为key,value为描述符类产生的对象)

class Room:
    def __init__(self,name,width,length):
        self.name=name
        self.width=width
        self.length=length

    @property
    def area(self):
        return self.width * self.length

r1=Room('alex',1,1)
print(r1.area)

@property回顾
@property回顾
class Lazyproperty:
    def __init__(self,func):
        print('--------->',func)
        self.func=func
    def __get__(self, instance, owner):
        print(instance)
        return self.func(instance)
class Room:
    def __init__(self,name,width,length):
        self.name=name
        self.width=width
        self.length=length
    # @property  #cal_area=property(cal_area)
    @Lazyproperty  #为room增加描述符,cal_area被Lazyproperty代理  实例化 cal_area=func
    def cal_area(self):
        return self.width * self.length
r1=Room('厕所',100,100)
print(r1.cal_area)
利用描述符自定制property
class Foo:
    @property
    def AAA(self):
        print('get的时候运行')

    @AAA.setter
    def AAA(self,val):
        print('set的时候运行',val)

    @AAA.deleter
    def AAA(self):
        print('del的时候运行')

f1=Foo()
f1.AAA
f1.AAA='aaa'
del f1.AAA
property补充

 

posted @ 2017-03-18 17:47  清风徐来xyd  阅读(118)  评论(0编辑  收藏  举报