python 属性管理机制
1、私有属性
Python默认的成员函数和成员变量都是公开的,Python 私有属性和方法没有类似别的语言的public,private等关键词来修饰。
在python中定义私有变量只需要在变量名或函数名前加上 "___"两个下划线或者 ‘’一个下划线 也默认为私有属性,那么这个函数或变量就会为私有的了
声明该方法为私有方法,不能在类的外部调用,也不能被继承,但可以在类中被调用(调用私有属性、私有方法)
2、 dict
类调用 dict 属性,返s类属性和方法的字典。
实列调用 dict 属性,返回的值实列相关的实例属性
3、内置属性 slots
默认情况下,类的实例有一个字典用于存储属性。这对于具有很少实例变量的对象会浪费空间。当创建
大量实例时,空间消耗可能会变得尖锐。
可以通过在类定义中定义__ slots 来覆盖默认 dict 行为。 slots __ 声明接受一个实例变量序列,并在每个实例中只保留足够保存每个变量值的空间。因为没有为每个实例创建 __ dict __ ,所以节省空间。
定义过slots属性来限制类实例的属性,只能绑定slots指定的属性。不能添加slots之外的属性。
class WorkPrice:
# 类实例化时只能绑定下列熟悉,不能添加其他的熟悉
__slots__ = ("title", "money", "data")
2.4、自定义属性访问
可以定义下面的方法来自定义类实例的属性访问的含义(访问、赋值或者删除 x.name )。
object.getattr
当属性查找在通常的地方没有找到该属性时调用
object.getattribute
查找属性时,第一时间会调用该方法
object.setattr
设置属性时,调用该方法设置属性,
object.delattr
在del obj.attr删除属性时触发。
def __setattr__(self, key, value):
if key == 'title':
if not isinstance(value, str):
raise TypeError('title属性的值必须为str类型')
elif key == 'money':
if not isinstance(value, int):
raise TypeError('money属性的值必须为int类型')
super().__setattr__(key, value)
def __delattr__(self, item):
"""删除属性的方法"""
if item == 'data':
raise AttributeError('item属性不能删除')
else:
super().__delattr__(item)
def __getattribute__(self, item):
""" 获取属性对应的值 --- 使用 hasattr() 时会调用这个方法"""
try:
value = super().__getattribute__(item)
except AttributeError:
if item == 'money':
value = 0
else:
value = None
finally:
return value
def __getattr__(self, item):
""" 针对 属性不存在的情况,直接定义这个方法 """
if item == 'money':
return 0
else:
return f'{item}属性不存在'
练习题
“”"
第一题、自定义一个类
1、通过上课的相关知识点对这个类创建的对象,进行属性限制,对象只能设置这个三个属性: title money data
2、通过相关机制对设置的属性类型进行限制,title只能设置字符串类型数据
money设置为int类型数据 data可以设置为任意类型
3、通过相关机制实现,data 属性不能进行删除
4、当money属性不存在时,查询出来的结果显示为0,
“”"
解题思路:第一点使用 slots 进行属性限制;第二点重写 __setattr__方法,在方法中进行条件判断,同时进行类型的限制;第三点 重写 __delattr__方法,对于item为 data属性时则抛出异常,不进行删除操作;第四点 定义 __getattr__方法,判断item为money时则return 0 的数值。也可以重写 __getattribute__方法,进行异常捕捉,对于 属性值为 money时返回值为 0 .
具体实现代码:
class WorkPrice:
__slots__ = ("title", "money", "data")
def __setattr__(self, key, value):
if key == 'title':
if not isinstance(value, str):
raise TypeError('title属性的值必须为str类型')
elif key == 'money':
if not isinstance(value, int):
raise TypeError('money属性的值必须为int类型')
super().__setattr__(key, value)
def __delattr__(self, item):
"""删除属性的方法"""
if item == 'data':
raise AttributeError('item属性不能删除')
else:
super().__delattr__(item)
def __getattribute__(self, item):
""" 获取属性对应的值 --- 使用 hasattr() 时会调用这个方法"""
try:
value = super().__getattribute__(item)
return value
except AttributeError:
if item == 'money':
return 0
else:
raise AttributeError(f'{item}这个属性不存在')
def __getattr__(self, item):
""" 针对 属性不存在的情况,直接定义这个方法 """
if item == 'money':
return 0
else:
return f'{item}属性不存在'
w = WorkPrice()
w.title = '不知道'
w.data = '什么数据'
print(w.money)
# print(w.money1)
result = hasattr(w, 'money')
print(result)