# 描述符的应用class Aoo: def __init__(self,key,expected_type): self.key = key self.expected_type = expected_type def __get__(self,instance,owner): return instance.__dict__[self.key] def __set__(self,instance,value): if not isinstance(
# 描述符的应用
class Aoo:
def __init__(self,key,expected_type):
self.key = key
self.expected_type = expected_type
def __get__(self,instance,owner):
return instance.__dict__[self.key]
def __set__(self,instance,value):
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):
instance.__dict__pop(self.key)
class Foo:
name = Aoo("name",str)
age = Aoo("age",int)
def __init__(self,name,age):
self.name = name
self.age = age
r = Foo("lwj",18)
print(r.name)
print(r.age)
# 类的装饰器
def deco(obj):
obj.a = 2
obj.b = 20
return obj
@deco # Aoo = deco(Aoo)
class Aoo:
pass
Aoo()
print(Aoo.__dict__)
# 类的装饰器修订
def pice(**kwargs):
def deco(obj):
for key,values in kwargs.items():
setattr(obj,key,values)
return obj
return deco
@pice(a=2,x=20) # deco = pice(a=2,x=20) Aoo= deco(Aoo)
class Aoo:
pass
Aoo()
print(Aoo.__dict__)
# 类的装饰器应用
class Aoo:
def __init__(self,key,expected_type):
self.key = key
self.expected_type = expected_type
def __get__(self,instance,owner):
return instance.__dict__[self.key]
def __set__(self,instance,value):
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):
instance.__dict__pop(self.key)
def pice(**kwargs): # kwargs = {"name":str,"age":int}
def deco(obj): # obj = Foo
for key,values in kwargs.items(): # (("name",str),("age",int))
setattr(obj,key,Aoo(key,values)) # setattr(Foo,"name",Aoo("name",str))
return obj
return deco
@pice(name=str,age=int) # deco = pice(name=str,age=int) Foo = deco(Foo)
class Foo:
name = Aoo("name",str)
age = Aoo("age",int)
def __init__(self,name,age):
self.name = name
self.age = age
r = Foo("lwj",18)
print(r.__dict__)
__enter__ __exit__
上下文管理协议,即with语句,为了让一个对象兼容with语句,必须在这个对象的类中声明__enter_和__exit__方法
class Open:
def __init__(self,name):
self.name=name
def __enter__(self):
print("with语句,对象的__enter__被触发,有返回值则赋值给r声明的变量")
#return self
def __exit__(self,exc_type,exc_val,exc_tb):
print("with中代码块执行完毕时执行我")
with Open("a.txt")as r:
print("sb")
print("2222222")
__exit__()中三个参数分别代表异常类型,异常值和追溯信息,with语句中代码出现异常则with后的代码都无法执行
class Open:
def __init__(self,name):
self.name=name
def __enter__(self):
print("with语句,对象的__enter__被触发,有返回值则赋值给r声明的变量")
#return self
def __exit__(self,exc_type,exc_val,exc_tb):
print("with中代码块执行完毕时执行我")
with Open("a.txt")as r:
print("sb")
print(ssdasdad)
print("111111111111111")
print("2222222")
如果__exit__()返回值为True,那么异常会被清空,就好像什么都没发生一样,with后的语句正常执行
class Open:
def __init__(self,name):
self.name=name
def __enter__(self):
print("with语句,对象的__enter__被触发,有返回值则赋值给r声明的变量")
#return self
def __exit__(self,exc_type,exc_val,exc_tb):
print("with中代码块执行完毕时执行我")
return True
with Open("a.txt")as r:
print("sb")
print(ssdasdad)
print("111111111111111")
print("2222222")
1、引子
class Aoo:
pass
r = Aoo() # r 是通过Aoo类实例化的对象
python中一切皆对象,类本身也是一个对象,当使用关键字class的时候python解析器在加载class的时候就会创建一个对象(这里的对象指的是类而非类的实例)
上例可以看出r是由Aoo这个类产生的对象,而Aoo本身也是对象,那它又是由哪个类产生的呢?
type函数可以查看类型,也可以用来查看对象的类,二者都是一样的
print(type(r)) # 输出:<class ‘__main__.Aoo‘> 表示,obj 对象由Aoo类创建
print(type(Aoo)) # 输出:<type ‘type‘>
2、什么是元类
元类是类的类,是类的模板
元类是用来控制如何创建类的,正如类是创建对象的模板一样
元类是实例为类,正如类的实例为对象(r对象是Aoo的一个实例,Aoo类是type类的一个实例)
type是python的一个内建元类,用来直接控制生成类,python中任何class定义的类其实都是typr类实例化的对象
3、创建元类的两种方法
第一种:
class Aoo:
def __init__(self):
pass
第二种:
def __init__(self,name,age):
self,name = name
self.age = age
Aoo = type("Aoo",(object,),{"x":1,"__init__":__init__})
4、一个类没有声明自己的元类,默认它的元类就是type,除了使用元类type,用户也可以通过继承typr来自定义元类
class Mytepy(type):
def __init__(self,a,b,c):
pass
def __class__(self,*args,**kwargs):
obj = object.__new__(self) # obj = object.__new__(Aoo)
self.__init__(obj,*args,**kwargs) # Aoo.__init__(r,*args,**kwargs)
return obj # 返回 r
class Aoo(metaclass=Mytepy): # Aoo = Mytepr("Aoo",(object,),{"name":name}) ---> __init__
def __init__(self,name):
self.name = name
r = Aoo("lwj")
print(r.name)
利用描述符自定制property
class Lazyproperty:
def __init__(self,func):
self.func = func
def __get__(self,instance,owner):
if instance is None:
return self
res = self.func(instance) # res = self.area(r)
setattr(instance,self.func.__name__,res) # r,area,运行area的结果
return res
class Aoo:
def __init__(self,name,width,length):
self.name = name
self.width = width
self.length = length
@Lazyproperty # area = Lazypropery(area)
def area(self):
return self.width * self.length
r = Aoo("未知",2,20)
# 实例调用
print(r.area)
# 类调用
print(Aoo.area)
property补充
# 只有在属性AAA定义property后才能定义AAA.setter,AAA.deleter
class Aoo:
@property
def AAA(self):
print("get的时候运行我")
@AAA.setter
def AAA(self,val):
print("set的时候运行我")
@AAA.deleter
def AAA(self):
print("deleter的时候运行我")
r = Aoo()
r.AAA
r.AAA = "aaa"
del r.AAA
class Aoo:
def get_AAA(self):
print("get的时候运行我")
def set_AAA(self,val):
print("set的时候运行我")
def del_AAA(slef):
print("deleter的时候运行我")
AAA = property(get_AAA,set_AAA,del_AAA)
r = Aoo()
r.AAA
r.AAA = "aaa"
del r.AAA
property 用法
class Aoo:
def __init__(self):
# 原价
self.original_price = 100
# 折扣
self.discount = 0.8
@property
def price(self):
# 实际价格 = 原价 * 折扣
new_pirce = self.original_price * self.discount
return new_pirce
@price.setter
def price(self,value):
self.original_price = value
@price.deleter
def price(self):
del self.original_price
a = Aoo()
print(a.price) # 获取商品价格
a.price = 200 # 修改商品原价
print(a.price)
del a.price # 删除商品原价
# print(a.price)
