day28-python之property

1.property用法

# class Goods:
#     def __init__(self):
#         # 原价
#         self.original_price = 100
#         # 折扣
#         self.discount = 0.8
#
#     @property
#     def price(self):
#         # 实际价格 = 原价 * 折扣
#         new_price = self.original_price * self.discount
#         return new_price
#
#     @price.setter
#     def price(self, value):
#         self.original_price = value
#
#     @price.deleter
#     def price(self):
#         del self.original_price
class Goods:
    def __init__(self):
        self.original_price = 100
        self.discount = 0.8

    @property
    def  price(self):
        new_price = self.original_price * self.discount
        return  new_price

    @price.setter
    def price(self,value):
        self.original_price = value

    @price.deleter
    def price(self):
        del self.original_price
obj = Goods()
print(obj.price)
obj.price = 200
print(obj.price)
del obj.price
print(obj.price)

# obj = Goods()
# print(obj.price)        # 获取商品价格
# obj.price = 200   # 修改商品原价
# print(obj.price)
# del obj.price     # 删除商品原价
# print(obj.price)

2.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的时候运行我啊')
# #只有在属性AAA定义property后才能定义AAA.setter,AAA.deleter
# f1=Foo()
# f1.AAA
# f1.AAA='aaa'
# del f1.AAA


# class Foo:
#
#     def get_AAA(self):
#         print('get的时候运行我啊')
#     def set_AAA(self,val):
#         print('set的时候运行我啊',val)
#     def del_AAA(self):
#         print('del的时候运行我啊')
#
#     AAA=property(get_AAA,set_AAA,del_AAA)
# #只有在属性AAA定义property后才能定义AAA.setter,AAA.deleter
# f1=Foo()
# f1.AAA
# f1.AAA='aaa'
# del f1.AAA

 

3.上下文管理协议

# class Foo:
#     def __init__(self,name):
#         self.name=name
#
#     def __enter__(self):
#         print('执行enter')
#         return self
#
#     def __exit__(self, exc_type, exc_val, exc_tb):
#         print('执行exit')
#         print(exc_type)
#         print(exc_val)
#         print(exc_tb)
#         return True
 
# with Foo('a.txt') as f:
#     print(f)
#     print(asdfsaasdfasdfasdfasdfasfasdfasdfasdfasdfasfdasfd)  #触发__exit__
#     print(f.name)
#     print('-----------------')
#     print('-----------------')
#     print('-----------------')
#     print('-----------------')
#     print('-----------------')
#     print('-----------------')
#     print('-----------------')
# print('000000000000000000000000000000000000000000000')
with obj as  f:
'代码块'

1.with obj ----》触发obj.__enter__(),拿到返回值

2.as f----->f=返回值、

3.with obj as f 等同于 f=obj.__enter__()

4.执行代码块
一:没有异常的情况下,整个代码块运行完毕后去触发__exit__,它的三个参数都为None
二:有异常的情况下,从异常出现的位置直接触发__exit__
a:如果__exit__的返回值为True,代表吞掉了异常
b:如果__exit__的返回值不为True,代表吐出了异常
c:__exit__的的运行完毕就代表了整个with语句的执行完毕

#自省
hasattr(obj,'属性') #obj.属性 是否存在
getattr(obj,'属性') #获取obj.属性 不存在则报错
getattr(obj,'属性','默认值') #获取obj.属性 不存在不会报错,返回那个默认值
setattr(obj,'属性','属性的值') #obj.属性=属性的值
delattr(obj,'属性') #del obj.属性

#__getattr__,__setattr__,__delattr__
obj点的方式去操作属性时触发的方法

__getattr__:obj.属性 不存在时触发
__setattr__:obj.属性=属性的值 时触发
__delattr__:del obj.属性 时触发

#__getitem__,__setitem_,__delitem__
obj[‘属性’]的方式去操作属性时触发的方法

__getitem__:obj['属性'] 时触发
__setitem__:obj['属性']=属性的值 时触发
__delitem__:del obj['属性'] 时触发

#__get__,__set__,__delete__
描述就是一个新式类,这个类至少要实现上述三个方法的一个
class 描述符:
def __get__():
pass
def __set__():
pass
def __delete__():
pass

class 类:
name=描述符()

obj=类()
obj.name #get
obj.name='egon' #set
del obj.name #delete

#__del__:析构方法
垃圾回收时触发
4.元类介绍
# class Foo:
#      pass
#
# f1=Foo() #f1是通过Foo类实例化的对象
#
# print(type(f1))
# print(type(Foo))
#
# class Bar:
#     pass
#
# print(type(Bar))



# class Foo:
#     def __init__(self):
#         pass
# print(Foo)
# print(Foo.__dict__)
#
# def __init__(self,name,age):
#     self.name=name
#     self.age=age
# def test(self):
#     print('=====>')
 
# FFo=type('FFo',(object,),{'x':1,'__init__':__init__,'test':test})
# print(FFo)
# print(FFo.__dict__)
#
# f1=FFo('alex',18)
# print(f1.name)
# f1.test()

5.利用描述符自定制property

# class Lazyproperty:
#     def __init__(self,func):
#         # print('==========>',func)
#         self.func=func
#     def __get__(self, instance, owner):
#         print('get')
#         # print(instance)
#         # print(owner)
#         if instance is None:
#             return self
#         res=self.func(instance)
#         setattr(instance,self.func.__name__,res)
#         return res
    # def __set__(self, instance, value):
    #     pass
class Lazypropery:
    def __init__(self,func):
        self.func = func
    def __get__(self, instance, owner):
        print('get')
        if instance is None:
            return self
        res = self.func(instance)
        setattr(instance,self.func.__name__,res)
        return res
    def __set__(self, instance, value):
        pass
class Room:
    def __init__(self,name,width,length):
        self.name = name
        self.width = width
        self.length = length
    @Lazypropery
    def area(self):
        return  self.width*self.length
    @property
    def areal(self):
        return  self.width*self.length
print(Room.__dict__)
r1 = Room('厕所',1,1)
print(r1.__dict__)
# class Room:
#     def __init__(self,name,width,length):
#         self.name=name
#         self.width=width
#         self.length=length
#     # @property #area=property(area)
#     @Lazyproperty  #area=Lazypropery(area)
#     def area(self):
#         return self.width * self.length
#     @property  #test=property(test)
#     def area1(self):
#         return  self.width * self.length
# # print(Room.__dict__)
# r1=Room('厕所',1,1)
# print(r1.__dict__)

print(r1.area)
print(Room.__dict__)
#实例调用
# print(r1.area)
# print(Room.__dict__)

#类调用
# print(Room.area)
print(Room.area)
print(r1.test)
print(Room.test)
# print(r1.test)
# print(Room.test)
# print(r1.area1)
# print(r1.area1)
# print(r1.area1)
# print(r1.area1)

print(r1.areal)
print(r1.areal)
print(r1.areal)
print(r1.areal)
print(r1.areal)
print(r1.areal)

# print(r1.area)
# print(r1.__dict__)
#
# print(r1.area)
# print(r1.area)
# print(r1.area)
# print(r1.area)
# print(r1.area)
# print(r1.area)
# print(r1.area)
# print(r1.area)

6.类的装饰器

# def deco(func):
#     print('==========')
#     return func
#
# # @deco       #test=deco(test)
# # def test():
# #     print('test函数运行')
# # test()
#
# @deco #Foo=deco(Foo)
# class Foo:
#     pass





 

# 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__)

#一切皆对象
# # @deco #test=deco(test)
# def test():
#     print('test函数')
# test.x=1
# test.y=1
# print(test.__dict__)

7.装饰器修订版

# def Typed(**kwargs):
#     def deco(obj):
#         for key,val in kwargs.items():
#             # obj.key=val
#             setattr(obj,key,val)
#         return obj
#     return deco

def Typed(**kwargs):
    def deco(obj):
        for key,val in kwargs.items():
            setattr(obj,key,val)
        return obj
    return  deco

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

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

# @Typed(name='egon')  #@deco   ---->Bar=deco(Bar)
# class Bar:
#     pass
# print(Bar.name)

8.类的装饰器的应用

# 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 TypeError('%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 Typed:
    def __init__(self,key,expected_type):
        self.key = key
        self.expected_type = expected_type
    def __get__(self, instance, owner):
        print('get方法')
        return instance.__dict__[self.key]
    def __set__(self, instance, value):
        print('set方法')
        if not isinstance(value,self.expected_type):
            raise TypeError('%s 传入的类型不是%s'%(self.key,self.expected_type))
        instance.__dict__[self.key]=value
    def __delete__(self, instance):
        print('delete方法')
        instance.__dict__.pop(self.key)

def deco(**kwargs):
    def wrapper(obj):
        for key,val in kwargs.items():
            setattr(obj,key,Typed(key,val))
        return  obj
    return  wrapper

@deco(name=str,age=int)
class People:
    name = 'alex'
    def __init__(self,name,age,salary,gender,heigth):
        self.name = name
        self.age = age
        self.salary = salary
print(People.__dict__)
# 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))
#             # setattr(People,'name',Typed('name',str)) #People.name=Typed('name',str)
#         return obj
#     return wrapper
# @deco(name=str,age=int)  #@wrapper ===>People=wrapper(People)
# class People:
#     name='alex'
#     # name=Typed('name',str)
#     # age=Typed('age',int)
#     def __init__(self,name,age,salary,gender,heigth):
#         self.name=name
#         self.age=age
#         self.salary=salary
# # p1=People('213',13.3,13.3,'x','y')
# print(People.__dict__)

9.自定制classmethod

# class ClassMethod:
#     def __init__(self,func):
#         self.func=func
#     def __get__(self, instance, owner): #类来调用,instance为None,owner为类本身,实例来调用,instance为实例,owner为类本身,
#         def feedback(*args,**kwargs):
#             print('在这里可以加功能啊...')
#             return self.func(owner,*args,**kwargs)
#         return feedback
class ClassMethod:
    def __init__(self,func):
        self.func = func
    def __get__(self, instance, owner):
        def feedback(*args,**kwargs):
            print('在这里可以加功能啊...')
            return  self.func(owner,*args,**kwargs)
        return feedback

class People:
    name = 'linhaifeng'
    @ClassMethod
    def say_hi(cls,msg,x):
        print('你好啊,帅哥%s%s%s'%(cls,msg,x))

# People.say_hi('你那是偷心的贼',10)
# class People:
#     name='linhaifeng'
#     @ClassMethod # say_hi=ClassMethod(say_hi)
#     def say_hi(cls,msg,x):
#         print('你好啊,帅哥 %s %s %s' %(cls.name,msg,x))
#
# People.say_hi('你是那偷心的贼',10)
#
# p1=People()
# p1.say_hi('你是那偷心的贼',10)
p1 = People()
p1.say_hi('你那是',11)

10.自定义制元类

# class MyType(type):
#     def __init__(self,a,b,c):
#         print('元类的构造函数执行')
#         # print(a)
#         # print(b)
#         # print(c)
#     def __call__(self, *args, **kwargs):
#         # print('=-======>')
#         # print(self)
#         # print(args,kwargs)
#         obj=object.__new__(self) #object.__new__(Foo)-->f1
#         self.__init__(obj,*args,**kwargs)  #Foo.__init__(f1,*arg,**kwargs)
#         return obj
# class Foo(metaclass=MyType): #Foo=MyType(Foo,'Foo',(),{})---》__init__
#     def __init__(self,name):
#         self.name=name #f1.name=name
class MyType(type):
    def __init__(self,a,b,c):
        print('元类的构造函数执行')
    def __call__(self, *args, **kwargs):
        obj = object.__new__(self)
        self.__init__(obj,*args,**kwargs)
        return obj
class Foo(metaclass=MyType):
    def __init__(self,name):
        self.name = name

# print(Foo)
# f1 = Foo('alex')
# print(f1)

f1 = Foo('alex')
print(f1)
print(f1.__dict__)



# print(Foo)
# f1=Foo('alex')
# print(f1)

# f1=Foo('alex')
# print(f1)
# print(f1.__dict__)

11.自定义制元类精简版

# class MyType(type):
#     def __init__(self,a,b,c):
#         print('元类的构造函数执行')
#     def __call__(self, *args, **kwargs):
#         obj=object.__new__(self)
#         self.__init__(obj,*args,**kwargs)
#         return obj
# class Foo(metaclass=MyType):
#     def __init__(self,name):
#         self.name=name
# f1=Foo('alex')

class MyType(type):
    def __init__(self,a,b,c):
        print('元类的构造函数执行')
    def __call__(self, *args, **kwargs):
        obj = object.__new__(self)
        self.__init__(obj,*args,**kwargs)
        return obj

class Foo(metaclass=MyType):
    def __init__(self,name):
        self.name = name

f1 = Foo('alex')

 

posted @ 2019-08-19 20:21  有猿人  阅读(255)  评论(0编辑  收藏  举报