一、__slots__
- 作用
1.限制一个类可以设置的属性
2.只要一个类实现了这个属性,那么这个类的__dict__属性就不会生成
- 使用场景:
因为每次创建一个对象时,都会创建一个__dict__属性,如果一个类会被创建很多次,那么就可以使用__slots__来限制这个类必须的属性。这样可以节约内存
class Test(object):
__slots__ = ['name', 'sex'] # 规定这个类能够定义的属性;如果不限制,那么可以任意定义属性
t = Test()
t.name = 'test'
t.sex = 'man'
t.age = 18 # 定义失败,因为没有规定该属性;而如果没有 __slots__限制,那么是可以定义成功的
# t.age = 16 # 这里会报错,因为__slots__中没有age属性
# print(t.__dict__) # 因为实现了__slots__,所以__dict__属性不生成,会报错
二、 __setattr__、__getattribute__、__delattr__、__getattr__
1、__setattr__
- 作用
1.给一个类设置属性和值
2.也就是使用setattr(object, name, value)
和object.key = value
时调用
2、__getattribute__
- 作用
1.获取一个类的一个属性的值
2.也就是使用getattr(object, name, default)
和object.key
时调用
3、 __getattr__
- 调用时机/作用
1.当获取一个类一个不存在的属性值时,就调用这个方法
2.也就是使用getattr(object, name, default)
和object.key
去获取不存在的属性时调用
4、__delattr__
- 作用
1.删除一个类的一个属性时调用
delattr(object, name)和del object.key
2.查找的属性不存在,就调用这个方法,报异常
setattr(Test, 'name', 'lin')
n = getattr(Test, 'name')
print(n) # lin
delattr(Test, 'name')
# print(Test().name) # 报错,因为上面delattr删除了Test类的name属性
'''自定义属性的限制'''
class Test1(object):
def __init__(self, name):
self.name = name
def __setattr__(self, key, value):
"""给类设置属性的时候,调用这个方法"""
print(self) # <__main__.Test1 object at 0x00000000028106A0>
print(key) # name
print(value) # lin
super().__setattr__(key, value) # 需要调用父类的这个方法,来给类设置属性
t1 = Test1('lin')
'''
下面的语句会报错,因为重写了__setattr__方法,真正给类设置属性的是父类的这个方法,
所以需要调用父类的这个方法。调用了后,就可以正常运行。
'''
print(t1.name)
三、利用 __setattr__、__getattribute__、__delattr__、__getattr__这几个方法,可以对自定义属性进行一些限制操作
- 比如:
场景1:利用setattr方法,限制一个属性的值
场景2:利用delattr方法,可以防止一个属性被外部删除
场景3:利用getattr方法,可以设置在访问不存在的属性时,返回想要返回的值
- 代码:
'''
自定义属性的处理:
场景1:利用__setattr__方法,限制一个属性的值
场景2:利用__delattr__方法,可以防止一个属性被外部删除
场景3:利用__getattr__方法,可以设置在访问不存在的属性时,返回想要返回的值
'''
class Test2(object):
def __init__(self, age):
self.age = age
def __setattr__(self, key, value):
if key == 'age': # 如果设置的是age属性
value = 18 # 则固定值
super().__setattr__(key, value)
def __delattr__(self, item):
if item == 'age': # 如果删除的是age属性
print('不执行删除')
pass
else:
super().__delattr__(item)
def __getattribute__(self, item):
"""获取存在的属性时,调用这个方法"""
print("item是:", item) # item是: age
return super().__getattribute__(item) # 需要把获取到的属性返回去,否则是None
def __getattr__(self, item):
"""获取不存在的属性时,调用这个方法,会报异常AttributeError"""
print('getattr,获取不存在的属性==>', item) # getattr,获取不存在的属性==> sex
if item == 'sex': # 如果访问的不存在属性是sex
return '女' # 则返回默认值
else: # 访问的是其它不存在的属性,则依旧抛出这个异常
raise AttributeError
t2 = Test2('哈哈哈哈')
print(t2.sex) # 女
# print(t2.abc) # 报错AttributeError
t2.name = '哈哈'
print(t2.name) # 哈哈
delattr(t2, 'name') # 删除成功
# print(t2.name) # 删除成功,报错
# delattr(t2, 'age') # 删除失败,打印:不执行删除
# del t2.age
print(t2.age) # 18