一、__enter__、__exit__
用于上下文管理器协议
__enter__:
进入上下文(with操作对象时)__exit__:
退出上下文(with中的代码块执行完毕之后,执行__exit__()方法)
class MyOpen:
def __init__(self,filename,mode,encoding='utf-8'):
self.f=open(filename,mode,encoding=encoding)
def __enter__(self):
return self.f
def __exit__(self, exc_type, exc_val, exc_tb):
self.f.close()
with MyOpen('1.txt','r',encoding='utf-8') as f:
res=f.readline()
print("res",res)
执行结果:
res 666666666
二、__getitem__、__setitem__、__delitem__
__getitem__:
实现对索引取值的语法__setitem__:
实现索引赋值的语法(obj[索引]=值)__delitem__:
实现索引删除值得语法
class MyList:
def __init__(self,*args):
self.value=list(args)
def __getitem__(self, item):
"""
实现对索引取值的支持
:param item: 索引
:return:
"""
return self.value[item]
def __setitem__(self, key, value):
"""
实现索引赋值的语法 obbj[索引]=值
:param key: 索引值
:param value: 赋的值
:return:
"""
self.value[key]=value
def __delitem__(self, key):
"""
实现索引删除的值语法 del obj[索引]
:param key:索引值
:return:
"""
del self.value[key]
def __str__(self):
return str(self.value)
m1=MyList(11,22,33)
#实现通过索引取值
print(m1[2]) #————》m1.__getitem__(2)
#实现通过索引赋值
m1[0]=666 #————》m1.__setitem__(0,666)
print(m1[0])
#实现通过索引删除值
del m1[0] #————》m1.__delitem__(0)
print(m1)
执行结果:
33
666
[22, 33]
三、__setattr__、__delattr__、__getattr__、__getattribute__
__setattr__
:给对象设置属性__delattr__
:删除对象中的属性__getattr__
:当在__getattribute__(self,item)方法中获取不存在的属性时,到__getatte__(self,item)中触发的属性方法__getattribute__
:获得对象中的属性
class Demo:
def __setattr__(self, key, value):
"""
todo setattr(obj,属性名,属性值)
obj.属性=值
:param key: 属性名
:param value: 值
:return:
"""
super().__setattr__(key,value)
def __delattr__(self, key):
"""
del obj.属性名
:param key:obj.属性名
:return:
"""
super().__delattr__(key)
def __getattr__(self, item):
"""
获取属性不存在(__getattribute__)时,触发的属性方法
:param item:
:return:
"""
print('获取属性{}'.format(item))
return '该属性{}不存在'.format(item)
def __getattribute__(self, item):
"""
obj.属性名
getattr(obj,属性)
属性获取触发的方法
:param item:属性名称
:return:
"""
return super().__getattribute__(item)
m=Demo()
m.name=99
m.age=18
print(m.__dict__)
del m.age
print(m.__dict__)
print(m.uuuuuu)
执行结果:
—work1----
{‘name’: 99, ‘age’: 18}
{‘name’: 99}
获取属性uuuuuu
该属性uuuuuu不存在
四、自定义一个类
满足以下条件:
1、通过上课的相关知识点对这个类创建的对象,进行属性限制,对象只能设置这个三个属性: title money data
2、通过相关机制对设置的属性类型进行限制,title只能设置字符串类型数据
money设置为int类型数据 data可以设置为任意类型
3、通过相关机制实现,data 属性不能进行删除
4、类支持 obj[属性名] 这种语法获取属性值。
class Demo:
__slots__ = ['title', 'money', 'data']
def __init__(self, *args):
self.title, self.money, self.data = list(args)
# self.value=list(args)
# def __init__(self,title,money,data):
# self.title=title
# self.money=money
# self.data=data
def __setattr__(self, key, value):
if key == "title":
if not isinstance(value, str):
raise ValueError('title只能为字符串')
else:
super().__setattr__(key, value)
elif key == 'money':
if not isinstance(value, int):
raise ValueError('money只能设置为int类型')
else:
super().__setattr__(key, value)
else:
super().__setattr__(key, value)
def __delattr__(self, item):
if item == 'data':
raise ValueError('data不能删除')
else:
super().__delattr__(item)
def __getitem__(self, item): 重要
return self.__getattribute__(item) 重要
if __name__ == '__main__':
d = Demo('title1', 120, {"a": 1})
print(d)
print(d.title)
print(d.data)
d1 = Demo('12', 120, {"a": 1})
print(d1)
print(d1.title)
print(d1["title"])
执行结果:
<main.Demo object at 0x000001E57AB98C40>
title1
{‘a’: 1}
<main.Demo object at 0x000001E57AB98D40>
12
12