一.@property
在文章
python:面向对象程序设计及property装饰器
二.__slost__使用
先定义简单的一个类:
class Student:
def __init__(self,name,age):
self.name=name
self.age=age
由于Python是可以动态绑定属性和方法的,一次,可以对一个雷或者类实例绑定一个属性.如果对一个对象绑定一个属性,该属性支队当前对象起作用,类的其他对象是没有这个属性的,
如:
if __name__ == "__main__":
stu1 = Student('alex',18)
#对stu1对象绑定一个nickname属性
stu1.nickname = 'littel alex'
stu2 = Student('lisi',16)
print(stu1.nickname) #'littel alex'
# stu2没有nickname属性,因此出现异常
#print(stu2.nickname) #AttributeError: 'Student' object has no attribute 'nickname'
print(stu1.nickname) #'littel alex'
print(stu2.nickname) #AttributeError: 'Student' object has no attribute 'nickname'
在创建类时(如果没有使用__slots__属性),python会为每个实例串讲一个__dict__属性,以字典的形式存放每个实例的属性,我们分别打印stu1和sut2的__dict__属性:
print(stu1.__dict__)
print(stu2.__dict__)
'''
{'name': 'alex', 'age': 18, 'nickname': 'littel alex'}
{'name': 'lisi', 'age': 16}
'''
如果要对类的所有对象都绑定一个属性,name就要绑定在类上:
Student.nickname = 'litter student'
这时stu1和stu2都具有nickname属性了
如果进制对类进行属性的添加和删除,就要在定义类时定义一个特殊的__slots__属性即可,这样的类创建后将包含指定的元素,而没有__dict__属性,
如:
class Newstudent:
__slots__ = ('name','age')
def __init__(self,name,age):
self.name=name
self.age=age
if __name__ == "__main__":
stu1 = Newstudent('alex',1000)
#由于使用__slots__指定了属性,不能再进行绑定,
# 出现AttributeError: 'Newstudent' object has no attribute 'nickname'
# stu1.nickname = 'wusix',9000
#AttributeError: 'Newstudent' object has no attribute 'nickname'
#没有__dict__所以出现AttributeError
print('dict:',stu1.__dict__)
#AttributeError: 'Newstudent' object has no attribute '__dict__'
三.属性相关的特殊方法
通过@property装饰器可以快速简单的对属性进行控制,但是可读性差,因此,除了这种方式外,可以使用python内置的一些特殊方法老控制属性的存取,
这些方法见下表:
特殊方法 | 使用 | 描述 |
| v = obj.n | 返回obj对象的item属性 |
| obj.key = value | 将obj对象的key属性设置为value |
| v = obj.n | 删除obj对象的item属性 |
| dir(obj) | 返回obj对象的属性列表 |
| v = obj.n | 返回obj对象的item属性 |
例如通过上述方法对Student类中name属性进行控制:
def __setattr__(self, key, value):
if key == 'name':
if not isinstance(value,str):
raise AttributeError("form setarr:name must be s str obj")
self.__name = value
如果类中同事定义了__seattr__和@name.setter,执行哪一个?坑定是前者了.
'''
注意:如果要实现这些方法来对属性存取进行控制,应该左海条件判断,在设置的属性或值不符合时抛出AttributeError或ValueError.
'''
__getattribute__()和_getattr__()方法都用于获取属性,在寻找属性时,其中如果实现了则__getattr__()不会调用.并且__getattribute__()通常会导致递归调用,因此一般不需要实现该方法.