__item__系列: getitem setitem delitem 对对象做类似于字典的(增删改查)触发__item__系列
class Foo:
def init(self, name):
self.name = name
def getitem(self, item): # 在以对象名+['对象属性名'] 来模仿字典形式 dict[key] ##在以对象名+['对象属性名']时执行本函数
# print(item)
# print(666)
return self.__dict__[item] # 返回的是对象__dict__字典里的键(item)的值,这样写就实现功能了
def setitem(self, key, value): # 还是模仿字典,在以【对象名[key]=value】时执行,可以用这个方法为对象插入属性,属性名字必须是字符串(而且必须按照变量名命名规则命名)
self.__dict__[key] = value # 为了逼真点,在类的字典里加上一个键值对,这样写就可以真的添加了一个属性
# print(key)
# print(value)
# 删除时候执行del 对象['对象属性名’]
def delitem(self, key):
# print('del obj[key]时,我执行')
del self.__dict__[key] # 这样写就可以真的删除了
# del 对象.属性时候执行
def delattr(self, item):
super().__delattr__(item)
print(f'对象的{item}属性已经删除')
如果传入的是一个字符串那么就能实现切片的功能
f1 = Foo('sb')
print(f1['name'])
print(f1.__dict__)
f1['m23'] = 2
print(f1.__dict__)
print(f1.m23)
del f1['m23']
print(f1.__dict__)
print(Foo.__dict__)
__delattr__系列:
class Person:
def init(self, name):
self.name = name
def setattr(self, key, value):# 当设置对象成员属性的时,系统会自动调用
print(key, value)
self.__dict__[key] = value
def getattr(self, item):# 当访问不存在的对象属性时,系统会自动调用
if item == 'age':
return 123
else:
return 'default'
def delattr(self, item):# 当销毁对象的成员属性时,系统会自动调用
print('del', item)
xiaoming = Person('1234')
# 每个对象都有一个成员属性:dict
# 用于存放对象的属性,包括动态添加的
print(xiaoming.__dict__)
xiaoming.name = '小明'
print(xiaoming.name)
print(xiaoming.__dict__)
xiaoming.age = 18
print(xiaoming.age)
print(xiaoming.hello)
del xiaoming.age
delattr:
class Car:
refcount = 0
def init(self, power):
self.power = power
self.totaldistance = 0
self.dic = {1:2,2:3}
def delattr(self, name):
print(f"execute delattr:name={name}")
super().__delattr__(name) # 调用对象所属类的父类的__delattr__方法(也就是object类的__delattr__方法删除了属性name)
a = Car('卡车')
print(a.__dict__)
del a.power
print(a.__dict__)
del a.__dict__
# __dict__属性是删不掉的, 只能是清空
print(a.__dict__)
# {}
"""
执行结果:
{'power': '卡车', 'totaldistance': 0}
execute delattr:name=power
{'totaldistance': 0}
execute delattr:name=dict
{}
"""
enter __exit__成对出现
正常例子:
class A:
def init(self, text):
self.text = text
def enter(self): # 开启上下文管理器对象时触发此方法
self.text = self.text + '您来啦' # 第一步
print(11111)
return self # 必须!!!将实例化的对象返回f1
def exit(self, exc_type, exc_val, exc_tb): # 执行完上下文管理器对象f1时触发此方法
print(333) # 第三步
self.text = self.text + ',这就走啦'
def new(cls, *args, **kwargs):
print(44)
return super().__new__(cls) # 必须要有return,否则对象空间不会返回给__init__进而不会把属性传给地址
with A('大爷') as f1:
print(2222)
print(f1.text) # 第二步 (如果__enter__方法没有return self 那么不能执行 f1.text(因为这个创建还没完事) )
print(f1.text) # 第四步
扩展举例:
class Sample:
def enter(self):
return self
def exit(self, type, value, trace):
print ("type:", type)
print ("value:", value)
print ("trace:", trace)
def do_something(self):
bar = 1/0
return bar + 10
with Sample() as sample:
sample.do_something()
"""
执行结果:
C:\Python36\python.exe C:/python_text24/面向对象/双下划线方法.py
type: <class 'ZeroDivisionError'>
value: division by zero
trace: <traceback object at 0x000002A1AD781648>
Traceback (most recent call last):
File "C:/python_text24/面向对象/双下划线方法.py", line 104, in
sample.do_something()
File "C:/python_text24/面向对象/双下划线方法.py", line 100, in do_something
bar = 1/0
ZeroDivisionError: division by zero
"""